osd layer: Add GLPatchTable and retire DrawContext

In osd layer, we use GLPatchTable (D3D11PatchTable) as a
device-specific representation of FarPatchTables instead of
DrawContext. GLPatchTable may be used not only for drawing
but also for GPU eval APIs (not yet supported though.
We may add CudaPatchTable etc as needed).

The legacy gregory patch drawing buffers are carved out to
the separate class, named GLLegacyGregoryPatchTable.

Also face-varying data are split into client side for now, until
we add new and more robust face-varying drawing structure
(scheduled at 3.1 release)

Tentatively replicate PatchArray structure in GLPatchTables. It will
be revised in the upcoming change.

Shifting hard-coded SRV locations of legacy gregory buffers in HLSL shaders.
This commit is contained in:
Takahito Tejima 2015-05-20 14:36:57 -07:00
parent 1e89b93e7d
commit 109a3f5383
30 changed files with 1431 additions and 1608 deletions

View File

@ -22,10 +22,8 @@
// language governing permissions and limitations under the Apache License.
//
#ifndef COMMON_PATCH_COLORS_H
#define COMMON_PATCH_COLORS_H
#include <osd/drawContext.h>
#ifndef OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H
#define OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H
#include <far/patchTables.h>
@ -33,4 +31,4 @@
float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchDescriptor const & desc);
#endif /* COMMON_PATCH_COLORS_H */
#endif /* OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H */

View File

@ -25,7 +25,6 @@
#include <D3D11.h>
#include <D3Dcompiler.h>
#include <osd/d3d11DrawContext.h>
#include <far/error.h>
#include <osd/cpuD3D11VertexBuffer.h>
@ -467,10 +466,6 @@ public:
ss << "#define OSD_ENABLE_PATCH_CULL\n";
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";
ss << "#define OSD_NUM_ELEMENTS " << effectDesc.numElements << "\n";
// add ptex functions
ss << D3D11PtexMipmapTexture::GetShaderSource();
@ -741,7 +736,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::CpuEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -753,7 +748,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::OmpEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -765,7 +760,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::TbbEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -778,7 +773,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::CLD3D11VertexBuffer,
Osd::CLStencilTables,
Osd::CLEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
CLD3D11DeviceContext>(
refiner,
numVertexElements,
@ -792,7 +787,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::CudaD3D11VertexBuffer,
Osd::CudaStencilTables,
Osd::CudaEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -804,7 +799,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new Osd::Mesh<Osd::D3D11VertexBuffer,
Osd::D3D11StencilTables,
Osd::D3D11ComputeEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -821,21 +816,10 @@ createOsdMesh(int level, int kernel) {
//------------------------------------------------------------------------------
static void
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
bindProgram(Effect effect, OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = 6;
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
D3D11DrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
assert(g_pInputLayout);
@ -885,7 +869,6 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
__declspec(align(16))
struct Tessellation {
float TessLevel;
int GregoryQuadOffsetBase;
int PrimitiveIdBase;
};
@ -906,8 +889,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
Tessellation * pData = ( Tessellation* )MappedResource.pData;
pData->TessLevel = static_cast<float>(1 << g_tessLevel);
pData->GregoryQuadOffsetBase = patch.GetQuadOffsetIndex();
pData->PrimitiveIdBase = patch.GetPatchIndex();
pData->PrimitiveIdBase = patch.GetPrimitiveIdBase();
g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 );
}
@ -959,24 +941,12 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting);
g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbConfig);
if (g_mesh->GetDrawContext()->vertexBufferSRV) {
g_pd3dDeviceContext->VSSetShaderResources(0, 1, &g_mesh->GetDrawContext()->vertexBufferSRV);
}
if (g_mesh->GetDrawContext()->vertexValenceBufferSRV) {
g_pd3dDeviceContext->VSSetShaderResources(1, 1, &g_mesh->GetDrawContext()->vertexValenceBufferSRV);
}
if (g_mesh->GetDrawContext()->quadOffsetBufferSRV) {
g_pd3dDeviceContext->HSSetShaderResources(2, 1, &g_mesh->GetDrawContext()->quadOffsetBufferSRV);
}
if (g_mesh->GetDrawContext()->patchParamBufferSRV) {
g_pd3dDeviceContext->HSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->DSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->GSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->PSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
ID3D11ShaderResourceView *srv = g_mesh->GetPatchTable()->GetPatchParamSRV();
if (srv) {
g_pd3dDeviceContext->HSSetShaderResources(0, 1, &srv);
g_pd3dDeviceContext->DSSetShaderResources(0, 1, &srv);
g_pd3dDeviceContext->GSSetShaderResources(0, 1, &srv);
g_pd3dDeviceContext->PSSetShaderResources(0, 1, &srv);
}
g_pd3dDeviceContext->PSSetShaderResources(4, 1, g_osdPTexImage->GetTexelsSRV());
@ -1011,15 +981,16 @@ drawModel() {
UINT hOffsets = 0;
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::D3D11PatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer,
DXGI_FORMAT_R32_UINT, 0);
g_pd3dDeviceContext->IASetIndexBuffer(
g_mesh->GetPatchTable()->GetPatchIndexBuffer(),
DXGI_FORMAT_R32_UINT, 0);
// patch drawing
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
@ -1054,7 +1025,7 @@ drawModel() {
break;
}
break;
};
}
Effect effect;
effect.value = 0;
@ -1076,8 +1047,10 @@ drawModel() {
g_pd3dDeviceContext->IASetPrimitiveTopology(topology);
g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(),
patch.GetVertIndex(), 0);
g_pd3dDeviceContext->DrawIndexed(
patch.GetNumPatches() * desc.GetNumControlVertices(),
patch.GetIndexBase(), 0);
}
}
@ -1470,13 +1443,13 @@ initD3D11(HWND hWnd) {
D3D_FEATURE_LEVEL hFeatureLevel = D3D_FEATURE_LEVEL_11_0;
for(UINT driverTypeIndex=0; driverTypeIndex < numDriverTypes; driverTypeIndex++){
hDriverType = driverTypes[driverTypeIndex];
unsigned int deviceFlags = 0;
unsigned int deviceFlags = 0;
#ifndef NDEBUG
// XXX: this is problematic in some environments.
// deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
hr = D3D11CreateDeviceAndSwapChain(NULL,
hDriverType, NULL, deviceFlags, NULL, 0,
hDriverType, NULL, deviceFlags, NULL, 0,
D3D11_SDK_VERSION, &hDXGISwapChainDesc,
&g_pSwapChain, &g_pd3dDevice,
&hFeatureLevel, &g_pd3dDeviceContext);
@ -1491,30 +1464,29 @@ initD3D11(HWND hWnd) {
}
#ifndef NDEBUG
// set break points on directx errors
ID3D11Debug *d3dDebug = nullptr;
hr = g_pd3dDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug);
if (SUCCEEDED(hr)) {
// set break points on directx errors
ID3D11Debug *d3dDebug = nullptr;
hr = g_pd3dDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug);
if (SUCCEEDED(hr)) {
ID3D11InfoQueue *d3dInfoQueue = nullptr;
hr = d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue);
if (SUCCEEDED(hr)) {
ID3D11InfoQueue *d3dInfoQueue = nullptr;
hr = d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue);
if (SUCCEEDED(hr)) {
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
D3D11_MESSAGE_ID denied[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS };
D3D11_INFO_QUEUE_FILTER filter;
memset(&filter, 0, sizeof(filter));
filter.DenyList.NumIDs = _countof(denied);
filter.DenyList.pIDList = denied;
d3dInfoQueue->AddStorageFilterEntries(&filter);
D3D11_MESSAGE_ID denied[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS };
D3D11_INFO_QUEUE_FILTER filter;
memset(&filter, 0, sizeof(filter));
filter.DenyList.NumIDs = _countof(denied);
filter.DenyList.pIDList = denied;
d3dInfoQueue->AddStorageFilterEntries(&filter);
d3dInfoQueue->Release();
}
d3dDebug->Release();
}
d3dInfoQueue->Release();
}
d3dDebug->Release();
}
#endif
// create rasterizer

View File

@ -34,7 +34,6 @@ cbuffer Transform : register( b0 ) {
cbuffer Tessellation : register( b1 ) {
float TessLevel;
int GregoryQuadOffsetBase;
int PrimitiveIdBase;
};
@ -61,7 +60,7 @@ float OsdTessLevel()
}
int OsdGregoryQuadOffsetBase()
{
return GregoryQuadOffsetBase;
return 0;
}
int OsdPrimitiveIdBase()
{

View File

@ -25,7 +25,6 @@
#include <D3D11.h>
#include <D3Dcompiler.h>
#include <osd/d3d11DrawContext.h>
#include <far/error.h>
#include <osd/cpuD3D11VertexBuffer.h>
@ -57,7 +56,9 @@
#include <osd/d3d11ComputeEvaluator.h>
#include <osd/d3d11Mesh.h>
OpenSubdiv::Osd::D3D11MeshInterface *g_mesh;
#include <osd/d3d11LegacyGregoryPatchTable.h>
OpenSubdiv::Osd::D3D11MeshInterface *g_mesh = NULL;
OpenSubdiv::Osd::D3D11LegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL;
#include <common/vtr_utils.h>
#include "../common/stopwatch.h"
@ -321,7 +322,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::CpuEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -333,7 +334,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::OmpEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -345,7 +346,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuD3D11VertexBuffer,
Far::StencilTables,
Osd::TbbEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -358,7 +359,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CLD3D11VertexBuffer,
Osd::CLStencilTables,
Osd::CLEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
CLD3D11DeviceContext>(
refiner,
numVertexElements,
@ -372,7 +373,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CudaD3D11VertexBuffer,
Osd::CudaStencilTables,
Osd::CudaEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -384,7 +385,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::D3D11VertexBuffer,
Osd::D3D11StencilTables,
Osd::D3D11ComputeEvaluator,
Osd::D3D11DrawContext,
Osd::D3D11PatchTable,
ID3D11DeviceContext>(
refiner,
numVertexElements,
@ -396,6 +397,15 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
printf("Unsupported kernel %s\n", getKernelName(kernel));
}
// legacy gregory
delete g_legacyGregoryPatchTable;
g_legacyGregoryPatchTable = NULL;
if (g_endCap == kEndCapLegacyGregory) {
g_legacyGregoryPatchTable =
Osd::D3D11LegacyGregoryPatchTable::Create(
g_mesh->GetFarPatchTables(), g_pd3dDeviceContext);
}
// compute model bounding
float min[3] = { FLT_MAX, FLT_MAX, FLT_MAX};
float max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
@ -618,16 +628,16 @@ ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static void
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
bindProgram(Effect effect, OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
// only legacy gregory needs maxValence and numElements
// neither legacy gregory nor gregory basis need single crease
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int maxValence = g_mesh->GetMaxValence();
int numElements = 6;
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
@ -706,8 +716,9 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
Tessellation * pData = ( Tessellation* )MappedResource.pData;
pData->TessLevel = static_cast<float>(1 << g_tessLevel);
pData->GregoryQuadOffsetBase = patch.GetQuadOffsetIndex();
pData->PrimitiveIdBase = patch.GetPatchIndex();
pData->GregoryQuadOffsetBase = g_legacyGregoryPatchTable ?
g_legacyGregoryPatchTable->GetQuadOffsetsBase(patch.GetDescriptor().GetType()) : 0;
pData->PrimitiveIdBase = patch.GetPrimitiveIdBase();
g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 );
}
@ -761,22 +772,23 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
g_pd3dDeviceContext->PSSetConstantBuffers(2, 1, &g_pcbLighting);
g_pd3dDeviceContext->PSSetConstantBuffers(3, 1, &g_pcbMaterial);
if (g_mesh->GetDrawContext()->vertexBufferSRV) {
g_pd3dDeviceContext->VSSetShaderResources(0, 1, &g_mesh->GetDrawContext()->vertexBufferSRV);
ID3D11ShaderResourceView *srv = g_mesh->GetPatchTable()->GetPatchParamSRV();
if (srv) {
g_pd3dDeviceContext->HSSetShaderResources(0, 1, &srv); // t0
g_pd3dDeviceContext->DSSetShaderResources(0, 1, &srv);
g_pd3dDeviceContext->PSSetShaderResources(0, 1, &srv);
}
if (g_mesh->GetDrawContext()->vertexValenceBufferSRV) {
g_pd3dDeviceContext->VSSetShaderResources(1, 1, &g_mesh->GetDrawContext()->vertexValenceBufferSRV);
}
if (g_mesh->GetDrawContext()->quadOffsetBufferSRV) {
g_pd3dDeviceContext->HSSetShaderResources(2, 1, &g_mesh->GetDrawContext()->quadOffsetBufferSRV);
}
if (g_mesh->GetDrawContext()->patchParamBufferSRV) {
g_pd3dDeviceContext->HSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->DSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
g_pd3dDeviceContext->PSSetShaderResources(
3, 1, &g_mesh->GetDrawContext()->patchParamBufferSRV);
if (g_legacyGregoryPatchTable) {
ID3D11ShaderResourceView *vertexSRV =
g_legacyGregoryPatchTable->GetVertexSRV();
ID3D11ShaderResourceView *vertexValenceSRV =
g_legacyGregoryPatchTable->GetVertexValenceSRV();
ID3D11ShaderResourceView *quadOffsetsSRV =
g_legacyGregoryPatchTable->GetQuadOffsetsSRV();
g_pd3dDeviceContext->VSSetShaderResources(2, 1, &vertexSRV); // t2
g_pd3dDeviceContext->VSSetShaderResources(3, 1, &vertexValenceSRV);// t3
g_pd3dDeviceContext->HSSetShaderResources(4, 1, &quadOffsetsSRV); // t4
}
}
@ -796,32 +808,23 @@ display() {
ID3D11Buffer *buffer = g_mesh->BindVertexBuffer();
assert(buffer);
// vertex texture update for legacy gregory drawing
if (g_legacyGregoryPatchTable) {
g_legacyGregoryPatchTable->UpdateVertexBuffer(buffer,
g_mesh->GetNumVertices(),
6,
g_pd3dDeviceContext);
}
UINT hStrides = 6*sizeof(float);
UINT hOffsets = 0;
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::D3D11PatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
// cv drawing
#if 0
if (g_drawPatchCVs) {
bindProgram(kPoint, OpenSubdiv::Osd::DrawContext::PatchArray());
g_pd3dDeviceContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(),
patch.GetVertIndex(), 0);
}
}
#endif
g_pd3dDeviceContext->IASetIndexBuffer(
g_mesh->GetPatchTable()->GetPatchIndexBuffer(), DXGI_FORMAT_R32_UINT, 0);
// patch drawing
int patchCount[12]; // [Type] (see far/patchTables.h)
@ -829,7 +832,7 @@ display() {
int numDrawCalls = 0;
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::D3D11PatchTable::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
@ -868,13 +871,15 @@ display() {
break;
}
break;
};
}
bindProgram(GetEffect(), patch);
g_pd3dDeviceContext->IASetPrimitiveTopology(topology);
g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(), patch.GetVertIndex(), 0);
g_pd3dDeviceContext->DrawIndexed(
patch.GetNumPatches() * desc.GetNumControlVertices(),
patch.GetIndexBase(), 0);
}
g_fpsTimer.Stop();
@ -1254,7 +1259,8 @@ initD3D11(HWND hWnd) {
D3D11_RASTERIZER_DESC rasterDesc;
ZeroMemory(&rasterDesc, sizeof(rasterDesc));
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_NONE; // XXX
//rasterDesc.CullMode = D3D11_CULL_NONE; // XXX
rasterDesc.CullMode = D3D11_CULL_BACK; // XXX
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true;

View File

@ -45,7 +45,6 @@ GLFWmonitor* g_primary=0;
#include <osd/cpuEvaluator.h>
#include <osd/cpuVertexBuffer.h>
#include <osd/cpuGLVertexBuffer.h>
#include <osd/drawContext.h>
#include <osd/mesh.h>
#include <far/gregoryBasis.h>

View File

@ -42,7 +42,6 @@
GLFWwindow* g_window = 0;
GLFWmonitor* g_primary = 0;
#include <osd/glDrawContext.h>
#include <far/error.h>
#include <osd/cpuEvaluator.h>
@ -155,6 +154,51 @@ struct Program {
GLuint attrColor;
} g_defaultProgram;
struct FVarData
{
FVarData() :
textureBuffer(0) {
}
~FVarData() {
Release();
}
void Release() {
if (textureBuffer)
glDeleteTextures(1, &textureBuffer);
textureBuffer = 0;
}
void Create(OpenSubdiv::Far::PatchTables const *patchTables,
int fvarWidth, std::vector<float> const & fvarSrcData) {
Release();
OpenSubdiv::Far::ConstIndexArray indices =
patchTables->GetFVarPatchesValues(0);
// expand fvardata to per-patch array
std::vector<float> data;
data.reserve(indices.size() * fvarWidth);
for (int fvert = 0; fvert < (int)indices.size(); ++fvert) {
int index = indices[fvert] * fvarWidth;
for (int i = 0; i < fvarWidth; ++i) {
data.push_back(fvarSrcData[index++]);
}
}
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float),
&data[0], GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
}
GLuint textureBuffer;
} g_fvarData;
//------------------------------------------------------------------------------
static GLuint
compileShader(GLenum shaderType, const char *source) {
@ -362,7 +406,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark)
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
OpenSubdiv::Far::StencilTables,
OpenSubdiv::Osd::CpuEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -372,7 +416,9 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark)
InterpolateFVarData(*refiner, *shape, fvarData);
g_mesh->SetFVarDataChannel(shape->GetFVarWidth(), fvarData);
// set fvardata to texture buffer
g_fvarData.Create(g_mesh->GetFarPatchTables(),
shape->GetFVarWidth(), fvarData);
delete shape;
@ -397,7 +443,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark)
// -------- VAO
glBindVertexArray(g_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer());
glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer());
glEnableVertexAttribArray(0);
@ -672,21 +718,13 @@ public:
// assign texture locations
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
return config;
}
@ -733,50 +771,23 @@ updateUniformBlocks() {
static void
bindTextures() {
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()) {
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetFvarDataTextureBuffer());
g_mesh->GetPatchTable()->GetPatchParamTextureBuffer());
}
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER, g_fvarData.textureBuffer);
glActiveTexture(GL_TEXTURE0);
}
static GLenum
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
bindProgram(Effect effect, OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
// only legacy gregory needs maxValence and numElements
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int numElements = 3;
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
@ -787,14 +798,10 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
glUseProgram(program);
// bind standalone uniforms
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
if (uniformPrimitiveIdBase >=0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase());
// return primtype
GLenum primType;
@ -858,8 +865,8 @@ display() {
glBindVertexArray(g_vao);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
if (g_displayStyle == kWire)
glDisable(GL_CULL_FACE);
@ -869,12 +876,15 @@ display() {
// patch drawing
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
GLenum primType = bindProgram(GetEffect(), patch);
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
glDrawElements(
primType,
patch.GetNumPatches()*patch.GetDescriptor().GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
if (g_displayStyle == kWire)
glEnable(GL_CULL_FACE);
@ -896,12 +906,15 @@ display() {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
GLenum primType = bindProgram(GetEffect(/*uvDraw=*/ true), patch);
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
glDrawElements(
primType,
patch.GetNumPatches()*patch.GetDescriptor().GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

View File

@ -82,7 +82,6 @@
#include <osd/glVertexBuffer.h>
#endif
#include <osd/glDrawContext.h>
#include <osd/glMesh.h>
#include <common/vtr_utils.h>
@ -235,7 +234,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::CpuEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -245,7 +244,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::OmpEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -256,7 +255,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::TbbEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -267,7 +266,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::CLGLVertexBuffer,
Osd::CLStencilTables,
Osd::CLEvaluator,
Osd::GLDrawContext,
Osd::GLPatchTable,
CLDeviceContext>(
refiner,
numVertexElements,
@ -281,7 +280,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::CudaGLVertexBuffer,
Osd::CudaStencilTables,
Osd::CudaEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -292,7 +291,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::GLVertexBuffer,
Osd::GLStencilTablesTBO,
Osd::GLXFBEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -303,7 +302,7 @@ createOsdMesh(std::string const &kernel,
return new Osd::Mesh<Osd::GLVertexBuffer,
Osd::GLStencilTablesSSBO,
Osd::GLComputeEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -405,7 +404,7 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
glBindVertexArray(vao);
// bind vertex
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetDrawContext()->GetPatchIndexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetPatchTable()->GetPatchIndexBuffer());
glBindBuffer(GL_ARRAY_BUFFER, mesh->BindVertexBuffer());
glEnableVertexAttribArray(0);
@ -417,17 +416,17 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
(const void*)(sizeof(GLfloat)*3));
// bind patchparam
if (mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
if (mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
mesh->GetDrawContext()->GetPatchParamTextureBuffer());
mesh->GetPatchTable()->GetPatchParamTextureBuffer());
}
Osd::DrawContext::PatchArrayVector const & patches =
mesh->GetDrawContext()->GetPatchArrays();
Osd::GLPatchTable::PatchArrayVector const & patches =
mesh->GetPatchTable()->GetPatchArrays();
for (int i=0; i<(int)patches.size(); ++i) {
Osd::DrawContext::PatchArray const & patch = patches[i];
Osd::GLPatchTable::PatchArray const & patch = patches[i];
Far::PatchDescriptor desc = patch.GetDescriptor();
Far::PatchDescriptor::Type patchType = desc.GetType();
@ -457,13 +456,15 @@ void runTest(ShapeDesc const &shapeDesc, std::string const &kernel,
glProgramUniform4f(program, diffuseColor,
color[0], color[1], color[2], color[3]);
glProgramUniform1i(program, uniformPrimitiveIdBase,
patch.GetPatchIndex());
patch.GetPrimitiveIdBase());
} else {
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
}
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
glDrawElements(primType,
patch.GetNumPatches() * desc.GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
glDisableVertexAttribArray(0);

View File

@ -42,7 +42,6 @@
GLFWwindow* g_window=0;
GLFWmonitor* g_primary=0;
#include <osd/glDrawContext.h>
#include <far/error.h>
#include <far/ptexIndices.h>
@ -241,7 +240,7 @@ createOsdMesh() {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
OpenSubdiv::Far::StencilTables,
OpenSubdiv::Osd::CpuEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner, 3, 0, g_level, bits);
// compute model bounding
@ -265,7 +264,7 @@ createOsdMesh() {
// -------- VAO
glBindVertexArray(g_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer());
glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer());
glEnableVertexAttribArray(0);
@ -462,17 +461,8 @@ public:
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
glUniform1i(loc, 0); // GL_TEXTURE0
}
if (effectDesc.effect.paint) {
@ -586,25 +576,11 @@ static void bindTextures(Effect effect) {
glActiveTexture(GL_TEXTURE0);
} else {
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
glBindTexture(
GL_TEXTURE_BUFFER,
g_mesh->GetPatchTable()->GetPatchParamTextureBuffer());
}
// color ptex
@ -621,19 +597,10 @@ static void bindTextures(Effect effect) {
}
static GLuint
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
bindProgram(Effect effect, OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
effectDesc.maxValence = maxValence;
effectDesc.numElements = 3;
}
// lookup shader cache (compile the shader if needed)
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
@ -646,15 +613,10 @@ bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patc
if (uniformImageSize >= 0)
glUniform1i(uniformImageSize, g_pageSize);
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformPrimitiveIdBase >= 0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase());
return program;
@ -708,12 +670,12 @@ display() {
glBindVertexArray(g_vao);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
// patch drawing
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
GLenum primType = GL_PATCHES;
@ -724,8 +686,9 @@ display() {
glProgramUniform4f(program, diffuseColor, 1, 1, 1, 1);
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
patch.GetNumPatches() * desc.GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
glBindVertexArray(0);
@ -844,13 +807,13 @@ drawStroke(int x, int y) {
effect.paint = 1;
bindTextures(effect);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
// patch drawing
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
GLenum primType = GL_PATCHES;
@ -859,8 +822,9 @@ drawStroke(int x, int y) {
bindProgram(effect, patch);
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
patch.GetNumPatches() * desc.GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
glBindVertexArray(0);

View File

@ -49,8 +49,6 @@ GLFWmonitor* g_primary = 0;
#include <string>
#include <utility>
#include <algorithm>
#include <osd/glDrawContext.h>
#include <far/error.h>
#include <osd/cpuEvaluator.h>
@ -783,17 +781,8 @@ public:
GLint loc;
// patch textures
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
glUniform1i(loc, 0); // GL_TEXTURE0
}
// environment textures
@ -948,7 +937,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
OpenSubdiv::Far::StencilTables,
OpenSubdiv::Osd::CpuEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -958,7 +947,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
OpenSubdiv::Far::StencilTables,
OpenSubdiv::Osd::OmpEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -969,7 +958,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
OpenSubdiv::Far::StencilTables,
OpenSubdiv::Osd::TbbEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -981,7 +970,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CLGLVertexBuffer,
OpenSubdiv::Osd::CLStencilTables,
OpenSubdiv::Osd::CLEvaluator,
OpenSubdiv::Osd::GLDrawContext,
OpenSubdiv::Osd::GLPatchTable,
CLDeviceContext>(
refiner,
numVertexElements,
@ -995,7 +984,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CudaGLVertexBuffer,
OpenSubdiv::Osd::CudaStencilTables,
OpenSubdiv::Osd::CudaEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -1007,7 +996,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::GLVertexBuffer,
OpenSubdiv::Osd::GLStencilTablesTBO,
OpenSubdiv::Osd::GLXFBEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -1020,7 +1009,7 @@ createOsdMesh(int level, int kernel) {
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::GLVertexBuffer,
OpenSubdiv::Osd::GLStencilTablesSSBO,
OpenSubdiv::Osd::GLComputeEvaluator,
OpenSubdiv::Osd::GLDrawContext>(
OpenSubdiv::Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -1051,7 +1040,7 @@ createOsdMesh(int level, int kernel) {
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (float*)12);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer());
// ------ Cage VAO
glBindVertexArray(g_cageEdgeVAO);
@ -1201,27 +1190,10 @@ updateConstantUniformBlock() {
static void
bindTextures() {
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
#endif
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
g_mesh->GetPatchTable()->GetPatchParamTextureBuffer());
}
// other textures
@ -1273,18 +1245,9 @@ bindTextures() {
//------------------------------------------------------------------------------
static GLenum
bindProgram(Effect effect,
OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
effectDesc.maxValence = maxValence;
effectDesc.numElements = 3;
}
GLDrawConfig *config = g_shaderCache.GetDrawConfig(effectDesc);
if (!config) return 0;
@ -1293,15 +1256,10 @@ bindProgram(Effect effect,
glUseProgram(program);
// bind standalone uniforms
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
if (uniformPrimitiveIdBase >= 0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase());
GLenum primType;
switch(effectDesc.desc.GetType()) {
@ -1334,10 +1292,10 @@ drawModel() {
glBindVertexArray(g_vao);
// patch drawing
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
Effect effect;
effect.value = 0;
@ -1357,8 +1315,9 @@ drawModel() {
GLenum primType = bindProgram(effect, patch);
glDrawElements(primType,
patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
patch.GetNumPatches() * patch.GetDescriptor().GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
}
glBindVertexArray(0);

View File

@ -43,7 +43,6 @@ GLFWwindow* g_window=0;
GLFWmonitor* g_primary=0;
#include <far/error.h>
#include <osd/glDrawContext.h>
#include <osd/cpuEvaluator.h>
#include <osd/cpuGLVertexBuffer.h>
@ -83,7 +82,9 @@ GLFWmonitor* g_primary=0;
#endif
#include <osd/glMesh.h>
OpenSubdiv::Osd::GLMeshInterface *g_mesh;
#include <osd/glLegacyGregoryPatchTable.h>
OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
OpenSubdiv::Osd::GLLegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL;
#include <common/vtr_utils.h>
#include "../common/stopwatch.h"
@ -232,6 +233,55 @@ struct Program
GLuint attrColor;
} g_defaultProgram;
// XXX:
// this struct meant to be used as a stopgap entity until we fully implement
// face-varying stuffs into patch table.
//
struct FVarData
{
FVarData() :
textureBuffer(0) {
}
~FVarData() {
Release();
}
void Release() {
if (textureBuffer)
glDeleteTextures(1, &textureBuffer);
textureBuffer = 0;
}
void Create(OpenSubdiv::Far::PatchTables const *patchTables,
int fvarWidth, std::vector<float> const & fvarSrcData) {
Release();
OpenSubdiv::Far::ConstIndexArray indices =
patchTables->GetFVarPatchesValues(0);
// expand fvardata to per-patch array
std::vector<float> data;
data.reserve(indices.size() * fvarWidth);
for (int fvert = 0; fvert < (int)indices.size(); ++fvert) {
int index = indices[fvert] * fvarWidth;
for (int i = 0; i < fvarWidth; ++i) {
data.push_back(fvarSrcData[index++]);
}
}
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float),
&data[0], GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
}
GLuint textureBuffer;
} g_fvarData;
static void
checkGLErrors(std::string const & where = "")
{
@ -532,7 +582,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::CpuEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -542,7 +592,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::OmpEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -553,7 +603,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CpuGLVertexBuffer,
Far::StencilTables,
Osd::TbbEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -566,7 +616,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CLGLVertexBuffer,
Osd::CLStencilTables,
Osd::CLEvaluator,
Osd::GLDrawContext,
Osd::GLPatchTable,
CLDeviceContext>(
refiner,
numVertexElements,
@ -580,7 +630,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::CudaGLVertexBuffer,
Osd::CudaStencilTables,
Osd::CudaEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -592,7 +642,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::GLVertexBuffer,
Osd::GLStencilTablesTBO,
Osd::GLXFBEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -605,7 +655,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
g_mesh = new Osd::Mesh<Osd::GLVertexBuffer,
Osd::GLStencilTablesSSBO,
Osd::GLComputeEvaluator,
Osd::GLDrawContext>(
Osd::GLPatchTable>(
refiner,
numVertexElements,
numVaryingElements,
@ -624,7 +674,17 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
InterpolateFVarData(*refiner, *shape, fvarData);
g_mesh->SetFVarDataChannel(shape->GetFVarWidth(), fvarData);
// set fvardata to texture buffer
g_fvarData.Create(g_mesh->GetFarPatchTables(),
shape->GetFVarWidth(), fvarData);
}
// legacy gregory
delete g_legacyGregoryPatchTable;
g_legacyGregoryPatchTable = NULL;
if (g_endCap == kEndCapLegacyGregory) {
g_legacyGregoryPatchTable =
Osd::GLLegacyGregoryPatchTable::Create(g_mesh->GetFarPatchTables());
}
if (not doAnim) {
@ -656,7 +716,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
// -------- VAO
glBindVertexArray(g_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetDrawContext()->GetPatchIndexBuffer());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_mesh->GetPatchTable()->GetPatchIndexBuffer());
glBindBuffer(GL_ARRAY_BUFFER, g_mesh->BindVertexBuffer());
glEnableVertexAttribArray(0);
@ -994,19 +1054,20 @@ public:
// assign texture locations
GLint loc;
glUseProgram(program);
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
glUniform1i(loc, 0); // GL_TEXTURE0
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
// for legacy gregory patches
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
glUseProgram(0);
@ -1089,37 +1150,36 @@ updateUniformBlocks() {
static void
bindTextures() {
// bind patch textures
if (g_mesh->GetDrawContext()->GetVertexTextureBuffer()) {
if (g_mesh->GetPatchTable()->GetPatchParamTextureBuffer()) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexTextureBuffer());
g_mesh->GetPatchTable()->GetPatchParamTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer()) {
if (true) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetVertexValenceTextureBuffer());
g_fvarData.textureBuffer);
}
if (g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer()) {
// legacy gregory
if (g_legacyGregoryPatchTable) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetQuadOffsetsTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetPatchParamTextureBuffer()) {
g_legacyGregoryPatchTable->GetVertexTextureBuffer());
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetPatchParamTextureBuffer());
}
if (g_mesh->GetDrawContext()->GetFvarDataTextureBuffer()) {
g_legacyGregoryPatchTable->GetVertexValenceTextureBuffer());
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_BUFFER,
g_mesh->GetDrawContext()->GetFvarDataTextureBuffer());
g_legacyGregoryPatchTable->GetQuadOffsetsTextureBuffer());
}
glActiveTexture(GL_TEXTURE0);
}
static GLenum
bindProgram(Effect effect,
OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), effect);
// only legacy gregory needs maxValence and numElements
@ -1127,7 +1187,7 @@ bindProgram(Effect effect,
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
if (patch.GetDescriptor().GetType() == Descriptor::GREGORY or
patch.GetDescriptor().GetType() == Descriptor::GREGORY_BOUNDARY) {
int maxValence = g_mesh->GetDrawContext()->GetMaxValence();
int maxValence = g_mesh->GetMaxValence();
int numElements = (g_displayStyle == kInterleavedVaryingColor ? 7 : 3);
effectDesc.maxValence = maxValence;
effectDesc.numElements = numElements;
@ -1146,14 +1206,20 @@ bindProgram(Effect effect,
glUseProgram(program);
// bind standalone uniforms
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
GLint uniformPrimitiveIdBase =
glGetUniformLocation(program, "PrimitiveIdBase");
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, patch.GetQuadOffsetIndex());
if (uniformPrimitiveIdBase >=0)
glUniform1i(uniformPrimitiveIdBase, patch.GetPatchIndex());
glUniform1i(uniformPrimitiveIdBase, patch.GetPrimitiveIdBase());
// legacy gregory
if (g_endCap == kEndCapLegacyGregory) {
GLint uniformGregoryQuadOffsetBase =
glGetUniformLocation(program, "GregoryQuadOffsetBase");
int quadOffsetBase =
g_legacyGregoryPatchTable->GetQuadOffsetsBase(patch.GetDescriptor().GetType());
if (uniformGregoryQuadOffsetBase >= 0)
glUniform1i(uniformGregoryQuadOffsetBase, quadOffsetBase);
}
// return primtype
GLenum primType;
@ -1207,7 +1273,13 @@ display() {
g_transformData.ProjectionMatrix);
// make sure that the vertex buffer is interoped back as a GL resources.
g_mesh->BindVertexBuffer();
GLuint vbo = g_mesh->BindVertexBuffer();
// vertex texture update for legacy gregory drawing
if (g_legacyGregoryPatchTable) {
glActiveTexture(GL_TEXTURE1);
g_legacyGregoryPatchTable->UpdateVertexBuffer(vbo);
}
if (g_displayStyle == kVaryingColor)
g_mesh->BindVaryingBuffer();
@ -1225,8 +1297,8 @@ display() {
glBindVertexArray(g_vao);
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
g_mesh->GetDrawContext()->GetPatchArrays();
OpenSubdiv::Osd::GLPatchTable::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
// patch drawing
int patchCount[13]; // [Type] (see far/patchTables.h)
@ -1242,7 +1314,7 @@ display() {
// core draw-calls
for (int i=0; i<(int)patches.size(); ++i) {
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
OpenSubdiv::Osd::GLPatchTable::PatchArray const & patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
@ -1252,8 +1324,10 @@ display() {
GLenum primType = bindProgram(GetEffect(), patch);
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
glDrawElements(primType,
patch.GetNumPatches() * desc.GetNumControlVertices(),
GL_UNSIGNED_INT,
(void *)(patch.GetIndexBase() * sizeof(unsigned int)));
++numDrawCalls;
}
@ -1395,6 +1469,10 @@ uninitGL() {
if (g_mesh)
delete g_mesh;
if (g_legacyGregoryPatchTable)
delete g_legacyGregoryPatchTable;
}
//------------------------------------------------------------------------------

View File

@ -30,7 +30,6 @@ set(CPU_SOURCE_FILES
cpuEvaluator.cpp
cpuKernel.cpp
cpuVertexBuffer.cpp
drawContext.cpp
)
set(GPU_SOURCE_FILES )
@ -48,7 +47,6 @@ set(PUBLIC_HEADER_FILES
mesh.h
nonCopyable.h
opengl.h
drawContext.h
vertexDescriptor.h
)
@ -106,7 +104,8 @@ list(APPEND DOXY_HEADER_FILES ${TBB_PUBLIC_HEADERS})
# GL code & dependencies
set(GL_PUBLIC_HEADERS
cpuGLVertexBuffer.h
glDrawContext.h
glLegacyGregoryPatchTable.h
glPatchTable.h
glVertexBuffer.h
glMesh.h
glslPatchShaderSource.h
@ -115,7 +114,8 @@ set(GL_PUBLIC_HEADERS
if( OPENGL_FOUND OR OPENGLES_FOUND )
list(APPEND GPU_SOURCE_FILES
cpuGLVertexBuffer.cpp
glDrawContext.cpp
glLegacyGregoryPatchTable.cpp
glPatchTable.cpp
glVertexBuffer.cpp
glslPatchShaderSource.cpp
)
@ -182,7 +182,8 @@ list(APPEND DOXY_HEADER_FILES ${GL_4_3_PUBLIC_HEADERS})
set(DXSDK_PUBLIC_HEADERS
cpuD3D11VertexBuffer.h
d3d11ComputeEvaluator.h
d3d11DrawContext.h
d3d11LegacyGregoryPatchTable.h
d3d11PatchTable.h
d3d11VertexBuffer.h
d3d11Mesh.h
hlslPatchShaderSource.h
@ -191,7 +192,8 @@ if( DXSDK_FOUND )
list(APPEND GPU_SOURCE_FILES
cpuD3D11VertexBuffer.cpp
d3d11ComputeEvaluator.cpp
d3d11DrawContext.cpp
d3d11LegacyGregoryPatchTable.cpp
d3d11PatchTable.cpp
d3d11VertexBuffer.cpp
hlslPatchShaderSource.cpp
)

View File

@ -1,303 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/d3d11DrawContext.h"
#include <D3D11.h>
#include <string.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
D3D11DrawContext::D3D11DrawContext(int maxValence) :
DrawContext(maxValence),
patchIndexBuffer(NULL),
patchParamBuffer(NULL),
patchParamBufferSRV(NULL),
fvarDataBuffer(NULL),
fvarDataBufferSRV(NULL),
vertexBufferSRV(NULL),
vertexValenceBuffer(NULL),
vertexValenceBufferSRV(NULL),
quadOffsetBuffer(NULL),
quadOffsetBufferSRV(NULL)
{
}
D3D11DrawContext::~D3D11DrawContext()
{
if (patchIndexBuffer) patchIndexBuffer->Release();
if (patchParamBuffer) patchParamBuffer->Release();
if (patchParamBufferSRV) patchParamBufferSRV->Release();
if (fvarDataBuffer) fvarDataBuffer->Release();
if (fvarDataBufferSRV) fvarDataBufferSRV->Release();
if (vertexBufferSRV) vertexBufferSRV->Release();
if (vertexValenceBuffer) vertexValenceBuffer->Release();
if (vertexValenceBufferSRV) vertexValenceBufferSRV->Release();
if (quadOffsetBuffer) quadOffsetBuffer->Release();
if (quadOffsetBufferSRV) quadOffsetBufferSRV->Release();
};
D3D11DrawContext *
D3D11DrawContext::Create(Far::PatchTables const *patchTables,
ID3D11DeviceContext *pd3d11DeviceContext)
{
int maxValence = patchTables->GetMaxValence();
D3D11DrawContext * result = new D3D11DrawContext(maxValence);
if (result->create(*patchTables, pd3d11DeviceContext))
return result;
delete result;
return NULL;
}
bool
D3D11DrawContext::create(Far::PatchTables const &patchTables,
ID3D11DeviceContext *pd3d11DeviceContext)
{
// adaptive patches
_isAdaptive = patchTables.IsFeatureAdaptive();
ID3D11Device *pd3d11Device = NULL;
pd3d11DeviceContext->GetDevice(&pd3d11Device);
assert(pd3d11Device);
// Process PTable
Far::PatchTables::PatchVertsTable const & ptables = patchTables.GetPatchControlVerticesTable();
D3D11_BUFFER_DESC bd;
bd.ByteWidth = (int)ptables.size() * sizeof(int);
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(int);
HRESULT hr = pd3d11Device->CreateBuffer(&bd, NULL, &patchIndexBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_MAPPED_SUBRESOURCE mappedResource;
hr = pd3d11DeviceContext->Map(patchIndexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr)) {
return false;
}
unsigned int * indexBuffer = (unsigned int *) mappedResource.pData;
memcpy(indexBuffer, &ptables[0], ptables.size() * sizeof(unsigned int));
pd3d11DeviceContext->Unmap(patchIndexBuffer, 0);
DrawContext::ConvertPatchArrays(patchTables, _patchArrays);
// allocate and initialize additional buffer data
// create patch param buffer
Far::PatchParamTable const & patchParamTables =
patchTables.GetPatchParamTable();
if (not patchParamTables.empty()) {
int numElements = (int)patchParamTables.size(),
elementSize = sizeof(Far::PatchParam);
unsigned int const * values =
reinterpret_cast<unsigned int const *>(&patchParamTables[0]);
std::vector<unsigned int> buffer;
bool useSingleCrease = not patchTables.GetSharpnessIndexTable().empty();
if (useSingleCrease) {
// if indexed sharpnesses exists, flatten them and interleave into 3-component buffer
packSharpnessValues(patchTables, buffer);
elementSize += sizeof(float);
values = &buffer[0];
}
bd.ByteWidth = numElements * elementSize;
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, &patchParamBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = useSingleCrease ? DXGI_FORMAT_R32G32B32_UINT : DXGI_FORMAT_R32G32_UINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = numElements;
hr = pd3d11Device->CreateShaderResourceView(
patchParamBuffer, &srvd, &patchParamBufferSRV);
if (FAILED(hr)) {
return false;
}
hr = pd3d11DeviceContext->Map(patchParamBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr)) {
return false;
}
unsigned int *dst = (unsigned int *) mappedResource.pData;
memcpy(dst, values, numElements * elementSize);
pd3d11DeviceContext->Unmap(patchParamBuffer, 0);
}
// create vertex valence buffer and vertex texture
Far::PatchTables::VertexValenceTable const &
valenceTable = patchTables.GetVertexValenceTable();
if (not valenceTable.empty()) {
D3D11_BUFFER_DESC bd;
bd.ByteWidth = UINT(valenceTable.size() * sizeof(unsigned int));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(unsigned int);
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &valenceTable[0];
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &vertexValenceBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = DXGI_FORMAT_R32_SINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = UINT(valenceTable.size());
hr = pd3d11Device->CreateShaderResourceView(vertexValenceBuffer, &srvd, &vertexValenceBufferSRV);
if (FAILED(hr)) {
return false;
}
}
Far::PatchTables::QuadOffsetsTable const &
quadOffsetTable = patchTables.GetQuadOffsetsTable();
if (not quadOffsetTable.empty()) {
D3D11_BUFFER_DESC bd;
bd.ByteWidth = UINT(quadOffsetTable.size() * sizeof(unsigned int));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(unsigned int);
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &quadOffsetTable[0];
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &quadOffsetBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = DXGI_FORMAT_R32_SINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = UINT(quadOffsetTable.size());
hr = pd3d11Device->CreateShaderResourceView(quadOffsetBuffer, &srvd, &quadOffsetBufferSRV);
if (FAILED(hr)) {
return false;
}
}
return true;
}
bool
D3D11DrawContext::SetFVarDataTexture(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & fvarData,
ID3D11DeviceContext *pd3d11DeviceContext) {
if (not fvarData.empty()) {
FVarData fvarDataTable;
packFVarData(patchTables, fvarWidth, fvarData, fvarDataTable);
ID3D11Device *pd3d11Device = NULL;
pd3d11DeviceContext->GetDevice(&pd3d11Device);
assert(pd3d11Device);
D3D11_BUFFER_DESC bd;
bd.ByteWidth = UINT(fvarDataTable.size() * sizeof(float));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(float);
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &fvarDataTable[0];
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &fvarDataBuffer);
if (FAILED(hr)) {
return false;
}
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 = UINT(fvarDataTable.size());
hr = pd3d11Device->CreateShaderResourceView(fvarDataBuffer, &srvd, &fvarDataBufferSRV);
if (FAILED(hr)) {
return false;
}
}
return true;
}
void
D3D11DrawContext::updateVertexTexture(ID3D11Buffer *vbo,
ID3D11DeviceContext *pd3d11DeviceContext,
int numVertices,
int numVertexElements)
{
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;
}
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,167 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H
#define OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H
#include "../version.h"
#include "../far/patchTables.h"
#include "../osd/drawContext.h"
#include <map>
struct ID3D11VertexShader;
struct ID3D11HullShader;
struct ID3D11DomainShader;
struct ID3D11GeometryShader;
struct ID3D11PixelShader;
struct ID3D11Buffer;
struct ID3D11ShaderResourceView;
struct ID3D11Device;
struct ID3D11DeviceContext;
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
/// \brief D3D11 specialized DrawContext class
///
/// D3D11DrawContext 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 D3D11DrawContext : public DrawContext {
public:
typedef ID3D11Buffer * VertexBufferBinding;
virtual ~D3D11DrawContext();
/// \brief Create an D3D11DrawContext from Far::PatchTables
///
/// @param patchTables A valid set of Far::PatchTables
///
/// @param pd3d11DeviceContext A device context
///
static D3D11DrawContext *Create(Far::PatchTables const *patchTables,
ID3D11DeviceContext *pd3d11DeviceContext);
/// template version for custom context (OpenCL) used by OsdMesh
template<typename DEVICE_CONTEXT>
static D3D11DrawContext *Create(Far::PatchTables const *patchtables,
DEVICE_CONTEXT context) {
return Create(patchtables, context->GetDeviceContext());
}
/// 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) {
if (vbo)
updateVertexTexture(vbo->BindD3D11Buffer(pd3d11DeviceContext),
pd3d11DeviceContext,
vbo->GetNumVertices(),
vbo->GetNumElements());
}
/// template version for custom context (OpenCL) used by OsdMesh
template<class VERTEX_BUFFER, class DEVICE_CONTEXT>
void UpdateVertexTexture(VERTEX_BUFFER *vbo, DEVICE_CONTEXT context) {
UpdateVertexTexture(vbo, context->GetDeviceContext());
}
ID3D11Buffer *patchIndexBuffer;
ID3D11Buffer *patchParamBuffer;
ID3D11ShaderResourceView *patchParamBufferSRV;
ID3D11Buffer *fvarDataBuffer;
ID3D11ShaderResourceView *fvarDataBufferSRV;
ID3D11ShaderResourceView *vertexBufferSRV;
ID3D11Buffer *vertexValenceBuffer;
ID3D11ShaderResourceView *vertexValenceBufferSRV;
ID3D11Buffer *quadOffsetBuffer;
ID3D11ShaderResourceView *quadOffsetBufferSRV;
/// Sets face-varying data buffer
///
/// @param patchTables A valid set of Far::PatchTables
///
/// @param pd3d11DeviceContext A device context
///
/// @param fvarWidth Total face-varying primvar data width in fvarData
///
/// @param fvarData Vector containing the face-varying data
///
/// @return True if the operation was successful
///
bool SetFVarDataTexture(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & fvarData,
ID3D11DeviceContext *pd3d11DeviceContext);
/// template version for custom context (OpenCL) used by OsdMesh
template<typename DEVICE_CONTEXT>
bool SetFVarDataTexture(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & fvarData,
DEVICE_CONTEXT context) {
return SetFVarDataTexture(patchTables, fvarWidth, fvarData,
context->GetDeviceContext());
}
private:
D3D11DrawContext(int maxValence);
// allocate buffers from patchTables
bool create(Far::PatchTables const &patchTables,
ID3D11DeviceContext *pd3d11DeviceContext);
void updateVertexTexture(ID3D11Buffer *vbo,
ID3D11DeviceContext *pd3d11DeviceContext,
int numVertices,
int numVertexElements);
int _numVertices;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_OSD_D3D11L_DRAW_CONTEXT_H */

View File

@ -0,0 +1,165 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/d3d11LegacyGregoryPatchTable.h"
#include <D3D11.h>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
D3D11LegacyGregoryPatchTable::D3D11LegacyGregoryPatchTable() :
_vertexValenceBuffer(0), _quadOffsetsBuffer(0),
_vertexSRV(0), _vertexValenceSRV(0), _quadOffsetsSRV(0) {
_quadOffsetsBase[0] = _quadOffsetsBase[1] = 0;
}
D3D11LegacyGregoryPatchTable::~D3D11LegacyGregoryPatchTable() {
if (_vertexValenceBuffer) _vertexValenceBuffer->Release();
if (_quadOffsetsBuffer) _quadOffsetsBuffer->Release();
if (_vertexSRV) _vertexSRV->Release();
if (_vertexValenceSRV) _vertexValenceSRV->Release();
if (_quadOffsetsSRV) _quadOffsetsSRV->Release();
}
D3D11LegacyGregoryPatchTable *
D3D11LegacyGregoryPatchTable::Create(Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *pd3d11DeviceContext) {
ID3D11Device *pd3d11Device = NULL;
pd3d11DeviceContext->GetDevice(&pd3d11Device);
assert(pd3d11Device);
D3D11LegacyGregoryPatchTable *result = new D3D11LegacyGregoryPatchTable();
Far::PatchTables::VertexValenceTable const &
valenceTable = farPatchTables->GetVertexValenceTable();
Far::PatchTables::QuadOffsetsTable const &
quadOffsetsTable = farPatchTables->GetQuadOffsetsTable();
if (not valenceTable.empty()) {
D3D11_BUFFER_DESC bd;
bd.ByteWidth = UINT(valenceTable.size() * sizeof(unsigned int));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(unsigned int);
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &valenceTable[0];
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData,
&result->_vertexValenceBuffer);
if (FAILED(hr)) {
delete result;
return NULL;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = DXGI_FORMAT_R32_SINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = UINT(valenceTable.size());
hr = pd3d11Device->CreateShaderResourceView(
result->_vertexValenceBuffer, &srvd,
&result->_vertexValenceSRV);
if (FAILED(hr)) {
delete result;
return NULL;
}
}
if (not quadOffsetsTable.empty()) {
D3D11_BUFFER_DESC bd;
bd.ByteWidth = UINT(quadOffsetsTable.size() * sizeof(unsigned int));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(unsigned int);
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &quadOffsetsTable[0];
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData,
&result->_quadOffsetsBuffer);
if (FAILED(hr)) {
delete result;
return NULL;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = DXGI_FORMAT_R32_SINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = UINT(quadOffsetsTable.size());
hr = pd3d11Device->CreateShaderResourceView(
result->_quadOffsetsBuffer, &srvd, &result->_quadOffsetsSRV);
if (FAILED(hr)) {
delete result;
return NULL;
}
}
result->_quadOffsetsBase[0] = 0;
result->_quadOffsetsBase[1] = 0;
// scan patchtable to find quadOffsetsBase.
for (int i = 0; i < farPatchTables->GetNumPatchArrays(); ++i) {
// GREGORY_BOUNDARY's quadoffsets come after GREGORY's.
if (farPatchTables->GetPatchArrayDescriptor(i) ==
Far::PatchDescriptor::GREGORY) {
result->_quadOffsetsBase[1] = farPatchTables->GetNumPatches(i) * 4;
break;
}
}
return result;
}
void
D3D11LegacyGregoryPatchTable::UpdateVertexBuffer(
ID3D11Buffer *vbo, int numVertices, int numVertexElements,
ID3D11DeviceContext *pd3d11DeviceContext) {
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,
&_vertexSRV);
if (FAILED(hr)) {
return;
}
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,102 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H
#define OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H
#include "../version.h"
#include "../far/patchTables.h"
#include "../osd/nonCopyable.h"
struct ID3D11Buffer;
struct ID3D11ShaderResourceView;
struct ID3D11Device;
struct ID3D11DeviceContext;
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
class D3D11LegacyGregoryPatchTable
: private NonCopyable<D3D11LegacyGregoryPatchTable> {
public:
~D3D11LegacyGregoryPatchTable();
template<typename DEVICE_CONTEXT>
static D3D11LegacyGregoryPatchTable *Create(
Far::PatchTables const *farPatchTables, DEVICE_CONTEXT context) {
return Create(farPatchTables, context->GetDeviceContext());
}
static D3D11LegacyGregoryPatchTable *Create(
Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *deviceContext);
void UpdateVertexBuffer(ID3D11Buffer *vbo,
int numVertices, int numVertexElements,
ID3D11DeviceContext *pd3d11DeviceContext);
ID3D11ShaderResourceView* GetVertexSRV() const {
return _vertexSRV;
}
ID3D11ShaderResourceView* GetVertexValenceSRV() const {
return _vertexValenceSRV;
}
ID3D11ShaderResourceView* GetQuadOffsetsSRV() const {
return _quadOffsetsSRV;
}
int GetQuadOffsetsBase(Far::PatchDescriptor::Type type) {
if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
return _quadOffsetsBase[1];
}
return _quadOffsetsBase[0];
}
protected:
D3D11LegacyGregoryPatchTable();
private:
ID3D11Buffer* _vertexValenceBuffer;
ID3D11Buffer* _quadOffsetsBuffer;
ID3D11ShaderResourceView* _vertexSRV;
ID3D11ShaderResourceView* _vertexValenceSRV;
ID3D11ShaderResourceView* _quadOffsetsSRV;
int _quadOffsetsBase[2]; // gregory, boundaryGregory
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_D3D11_LEGACY_GREGORY_PATCH_TABLE_H

View File

@ -28,14 +28,15 @@
#include "../version.h"
#include "../osd/mesh.h"
#include "../osd/d3d11DrawContext.h"
#include "../osd/d3d11PatchTable.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
typedef MeshInterface<D3D11DrawContext> D3D11MeshInterface;
typedef MeshInterface<D3D11PatchTable> D3D11MeshInterface;
} // end namespace Osd

View File

@ -0,0 +1,182 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/d3d11PatchTable.h"
#include <D3D11.h>
#include "../far/patchTables.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
D3D11PatchTable::D3D11PatchTable() :
_indexBuffer(0), _patchParamBuffer(0), _patchParamBufferSRV(0) {
}
D3D11PatchTable::~D3D11PatchTable() {
if (_indexBuffer) _indexBuffer->Release();
if (_patchParamBuffer) _patchParamBuffer->Release();
if (_patchParamBufferSRV) _patchParamBufferSRV->Release();
}
D3D11PatchTable *
D3D11PatchTable::Create(Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *pd3d11DeviceContext) {
D3D11PatchTable *instance = new D3D11PatchTable();
if (instance->allocate(farPatchTables, pd3d11DeviceContext))
return instance;
delete instance;
return 0;
}
bool
D3D11PatchTable::allocate(Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *pd3d11DeviceContext) {
ID3D11Device *pd3d11Device = NULL;
pd3d11DeviceContext->GetDevice(&pd3d11Device);
assert(pd3d11Device);
std::vector<int> buffer;
std::vector<unsigned int> ppBuffer;
// needs reserve?
int nPatchArrays = farPatchTables->GetNumPatchArrays();
// for each patchArray
for (int j = 0; j < nPatchArrays; ++j) {
PatchArray patchArray(farPatchTables->GetPatchArrayDescriptor(j),
farPatchTables->GetNumPatches(j),
(int)buffer.size(),
(int)ppBuffer.size()/3);
_patchArrays.push_back(patchArray);
// indices
Far::ConstIndexArray indices = farPatchTables->GetPatchArrayVertices(j);
for (int k = 0; k < indices.size(); ++k) {
buffer.push_back(indices[k]);
}
// patchParams
#if 0
// XXX: we need sharpness interface for patcharray or put sharpness
// into patchParam.
Far::ConstPatchParamArray patchParams =
farPatchTables->GetPatchParams(j);
for (int k = 0; k < patchParams.size(); ++k) {
float sharpness = 0.0;
ppBuffer.push_back(patchParams[k].faceIndex);
ppBuffer.push_back(patchParams[k].bitField.field);
ppBuffer.push_back(*((unsigned int *)&sharpness));
}
#else
// XXX: workaround. GetPatchParamTable() will be deprecated though.
Far::PatchParamTable const & patchParamTables =
farPatchTables->GetPatchParamTable();
std::vector<Far::Index> const &sharpnessIndexTable =
farPatchTables->GetSharpnessIndexTable();
int numPatches = farPatchTables->GetNumPatches(j);
for (int k = 0; k < numPatches; ++k) {
float sharpness = 0.0;
int patchIndex = (int)ppBuffer.size()/3;
if (patchIndex < (int)sharpnessIndexTable.size()) {
int sharpnessIndex = sharpnessIndexTable[patchIndex];
if (sharpnessIndex >= 0)
sharpness = farPatchTables->GetSharpnessValues()[sharpnessIndex];
}
ppBuffer.push_back(patchParamTables[patchIndex].faceIndex);
ppBuffer.push_back(patchParamTables[patchIndex].bitField.field);
ppBuffer.push_back(*((unsigned int *)&sharpness));
}
#endif
}
// index buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = (int)buffer.size() * sizeof(int);
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
bd.StructureByteStride = sizeof(int);
HRESULT hr = pd3d11Device->CreateBuffer(&bd, NULL, &_indexBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_MAPPED_SUBRESOURCE mappedResource;
hr = pd3d11DeviceContext->Map(_indexBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr)) {
return false;
}
unsigned int * indexBuffer = (unsigned int *) mappedResource.pData;
memcpy(indexBuffer, &buffer[0], buffer.size() * sizeof(unsigned int));
pd3d11DeviceContext->Unmap(_indexBuffer, 0);
// patchparam buffer
ZeroMemory(&bd, sizeof(bd));
bd.ByteWidth = (int)ppBuffer.size() * sizeof(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, &_patchParamBuffer);
if (FAILED(hr)) {
return false;
}
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
ZeroMemory(&srvd, sizeof(srvd));
srvd.Format = DXGI_FORMAT_R32G32B32_UINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = (int)ppBuffer.size()/3;
hr = pd3d11Device->CreateShaderResourceView(
_patchParamBuffer, &srvd, &_patchParamBufferSRV);
if (FAILED(hr)) {
return false;
}
hr = pd3d11DeviceContext->Map(_patchParamBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(hr)) {
return false;
}
unsigned int *dst = (unsigned int *) mappedResource.pData;
memcpy(dst, &ppBuffer[0], ppBuffer.size() * sizeof(int));
pd3d11DeviceContext->Unmap(_patchParamBuffer, 0);
return true;
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,125 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_GL_PATCH_TABLE_H
#define OPENSUBDIV3_OSD_GL_PATCH_TABLE_H
#include "../version.h"
#include <vector>
#include "../far/patchDescriptor.h"
#include "../osd/nonCopyable.h"
struct ID3D11Buffer;
struct ID3D11ShaderResourceView;
struct ID3D11Device;
struct ID3D11DeviceContext;
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far{
class PatchTables;
};
namespace Osd {
class D3D11PatchTable : private NonCopyable<D3D11PatchTable> {
public:
typedef ID3D11Buffer * VertexBufferBinding;
// XXX: this struct will be further refactored.
class PatchArray {
public:
PatchArray(Far::PatchDescriptor desc, int numPatches,
int indexBase, int primitiveIdBase) :
desc(desc), numPatches(numPatches), indexBase(indexBase),
primitiveIdBase(primitiveIdBase) {}
Far::PatchDescriptor const &GetDescriptor() const {
return desc;
}
int GetNumPatches() const {
return numPatches;
}
int GetIndexBase() const {
return indexBase;
}
int GetPrimitiveIdBase() const {
return primitiveIdBase;
}
private:
Far::PatchDescriptor desc;
int numPatches;
int indexBase; // an offset within the index buffer
int primitiveIdBase; // an offset within the patch param buffer
};
typedef std::vector<PatchArray> PatchArrayVector;
D3D11PatchTable();
~D3D11PatchTable();
template<typename DEVICE_CONTEXT>
static D3D11PatchTable *Create(Far::PatchTables const *farPatchTables,
DEVICE_CONTEXT context) {
return Create(farPatchTables, context->GetDeviceContext());
}
static D3D11PatchTable *Create(Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *deviceContext);
PatchArrayVector const &GetPatchArrays() const {
return _patchArrays;
}
/// Returns the index buffer containing the patch control vertices
ID3D11Buffer* GetPatchIndexBuffer() const {
return _indexBuffer;
}
/// Returns the SRV containing the patch parameter
ID3D11ShaderResourceView* GetPatchParamSRV() const {
return _patchParamBufferSRV;
}
protected:
// allocate buffers from patchTables
bool allocate(Far::PatchTables const *farPatchTables,
ID3D11DeviceContext *deviceContext);
PatchArrayVector _patchArrays;
ID3D11Buffer *_indexBuffer;
ID3D11Buffer *_patchParamBuffer;
ID3D11ShaderResourceView *_patchParamBufferSRV;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_GL_PATCH_TABLE_H

View File

@ -1,133 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/drawContext.h"
#include "../far/patchTables.h"
#include <cstring>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
DrawContext::~DrawContext() {}
void
DrawContext::ConvertPatchArrays(Far::PatchTables const &patchTables,
PatchArrayVector &osdPatchArrays) {
int narrays = patchTables.GetNumPatchArrays();
// allocate drawing patch arrays
osdPatchArrays.clear();
osdPatchArrays.reserve(narrays);
for (int array=0, pidx=0, vidx=0, qidx=0; array<narrays; ++array) {
Far::PatchDescriptor desc = patchTables.GetPatchArrayDescriptor(array);
int npatches = patchTables.GetNumPatches(array),
nverts = desc.GetNumControlVertices();
osdPatchArrays.push_back(PatchArray(desc, npatches, vidx, pidx, qidx));
vidx += npatches * nverts;
pidx += npatches;
qidx += (desc.GetType() == Far::PatchDescriptor::GREGORY) ? npatches*nverts : 0;
}
}
// note : it is likely that Far::PatchTables::GetPatchControlVerticesTable()
// will eventually be deprecated if control vertices cannot be kept
// in a single linear array of indices. This function will help
// packing patch control vertices for GPU buffers.
void
DrawContext::packPatchVerts(Far::PatchTables const & patchTables,
std::vector<Index> & dst) {
dst.resize(patchTables.GetNumControlVerticesTotal());
Index * ptr = &dst[0];
int narrays = patchTables.GetNumPatchArrays();
for (int array=0; array<narrays; ++array) {
Far::ConstIndexArray verts = patchTables.GetPatchArrayVertices(array);
memcpy(ptr, verts.begin(), verts.size()*sizeof(Index));
ptr += verts.size();
}
}
void
DrawContext::packSharpnessValues(Far::PatchTables const & patchTables,
std::vector<unsigned int> & dst) {
Far::PatchParamTable const & patchParamTables =
patchTables.GetPatchParamTable();
std::vector<int> const &sharpnessIndexTable =
patchTables.GetSharpnessIndexTable();
std::vector<float> const &sharpnessValues =
patchTables.GetSharpnessValues();
int npatches = (int)patchParamTables.size();
// PatchParam = sizeof(int)*2, 1 float for sharpness
dst.resize(npatches * (2 + 1));
for (int i = 0; i < npatches; ++i) {
float sharpness = sharpnessIndexTable[i] >= 0 ?
sharpnessValues[sharpnessIndexTable[i]] : 0.0f;
dst[i*3+0] = patchParamTables[i].faceIndex;
dst[i*3+1] = patchParamTables[i].bitField.field;
dst[i*3+2] = *((unsigned int *)&sharpness);
}
}
void
DrawContext::packFVarData(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & src, FVarData & dst) {
assert(fvarWidth and (not src.empty()));
// XXXX OsdMesh only accesses channel 0
Far::ConstIndexArray indices = patchTables.GetFVarPatchesValues(0);
dst.resize(indices.size() * fvarWidth);
float * ptr = &dst[0];
for (int fvert=0; fvert<(int)indices.size(); ++fvert, ptr+=fvarWidth) {
int index = indices[fvert] * fvarWidth;
assert(index<(int)src.size());
memcpy(ptr, &src[index], fvarWidth*sizeof(float));
}
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,197 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_DRAW_CONTEXT_H
#define OPENSUBDIV3_OSD_DRAW_CONTEXT_H
#include "../version.h"
#include "../far/patchDescriptor.h"
#include "../far/types.h"
#include <utility>
#include <string>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
class PatchTables;
}
namespace Osd {
/// \brief Base DrawContext class
///
/// DrawContext 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.
/// DrawContext processes FarPatchArrays from Far::PatchTables 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 DrawContext {
public:
typedef Far::Index Index;
class PatchArray {
public:
/// Constructor
///
/// @param desc Patch descriptor defines the type, pattern, rotation of
/// the patches in the array
///
/// @param npatches The number of patches in the array
///
/// @param vertIndex Index of the first control vertex in the array
///
/// @param patchIndex Index of the first patch in the array
///
/// @param qoIndex Index of the first quad-offset entry
///
PatchArray(Far::PatchDescriptor desc, int npatches,
Index vertIndex, Index patchIndex, Index qoIndex) :
_desc(desc), _npatches(npatches),
_vertIndex(vertIndex), _patchIndex(patchIndex), _quadOffsetIndex(qoIndex) { }
/// Returns a patch descriptor defining the type of patches in the array
Far::PatchDescriptor GetDescriptor() const {
return _desc;
}
/// Update a patch descriptor
void SetDescriptor(Far::PatchDescriptor desc) {
_desc = desc;
}
/// Returns the index of the first control vertex of the first patch
/// of this array in the global PTable
unsigned int GetVertIndex() const {
return _vertIndex;
}
/// Returns the global index of the first patch in this array (Used to
/// access ptex / fvar table data)
unsigned int GetPatchIndex() const {
return _patchIndex;
}
/// Returns the number of patches in the array
unsigned int GetNumPatches() const {
return _npatches;
}
/// Returns the number of patch indices in the array
unsigned int GetNumIndices() const {
return _npatches * _desc.GetNumControlVertices();
}
/// Returns the offset of quad offset table
unsigned int GetQuadOffsetIndex() const {
return _quadOffsetIndex;
}
/// Set num patches (used at batch glomming)
void SetNumPatches(int npatches) {
_npatches = npatches;
}
private:
Far::PatchDescriptor _desc;
int _npatches;
Index _vertIndex,
_patchIndex,
_quadOffsetIndex;
};
/// Constructor
DrawContext(int maxValence) : _isAdaptive(false), _maxValence(maxValence) {}
/// Descrtuctor
virtual ~DrawContext();
/// Returns true if the primitive attached to the context uses feature adaptive
/// subdivision
bool IsAdaptive() const {
return _isAdaptive;
}
typedef std::vector<PatchArray> PatchArrayVector;
PatchArrayVector const & GetPatchArrays() const {
return _patchArrays;
}
/// The writable accessor to the internal patch array (tentative).
/// We should have a different api something like ConvertPatchArrays().
PatchArrayVector &GetPatchArrays() {
return _patchArrays;
}
// processes FarPatchArrays and inserts requisite sub-patches for the arrays
// containing transition patches
static void ConvertPatchArrays(Far::PatchTables const &patchTables,
DrawContext::PatchArrayVector &osdPatchArrays);
// maxValence is needed for legacy gregorypatch drawing
int GetMaxValence() const {
return _maxValence;
}
typedef std::vector<float> FVarData;
protected:
static void packPatchVerts(Far::PatchTables const & patchTables,
std::vector<Index> & dst);
static void packSharpnessValues(Far::PatchTables const & patchTables,
std::vector<unsigned int> & dst);
static void packFVarData(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & src, FVarData & dst);
// XXXX: move to private member
PatchArrayVector _patchArrays;
bool _isAdaptive;
int _maxValence;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_OSD_DRAW_CONTEXT_H */

View File

@ -1,232 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glDrawContext.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
GLDrawContext::GLDrawContext(int maxValence) :
DrawContext(maxValence),
_patchIndexBuffer(0), _patchParamTextureBuffer(0), _fvarDataTextureBuffer(0),
_vertexTextureBuffer(0), _vertexValenceTextureBuffer(0), _quadOffsetsTextureBuffer(0)
{
}
GLDrawContext::~GLDrawContext()
{
glDeleteBuffers(1, &_patchIndexBuffer);
glDeleteTextures(1, &_vertexTextureBuffer);
glDeleteTextures(1, &_vertexValenceTextureBuffer);
glDeleteTextures(1, &_quadOffsetsTextureBuffer);
glDeleteTextures(1, &_patchParamTextureBuffer);
glDeleteTextures(1, &_fvarDataTextureBuffer);
}
template <typename T> static GLuint
createTextureBuffer(T const &data, GLint format, int offset=0)
{
GLuint buffer = 0, texture = 0;
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
glGenTextures(1, &texture);
glGenBuffers(1, &buffer);
#if defined(GL_EXT_direct_state_access)
if (glNamedBufferDataEXT and glTextureBufferEXT) {
glNamedBufferDataEXT(buffer, (data.size()-offset) * sizeof(typename T::value_type),
&data[offset], GL_STATIC_DRAW);
glTextureBufferEXT(texture, GL_TEXTURE_BUFFER, format, buffer);
} else {
#else
{
#endif
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);
glBindTexture(GL_TEXTURE_BUFFER, 0);
}
glDeleteBuffers(1, &buffer);
#endif
return texture;
}
GLDrawContext *
GLDrawContext::Create(Far::PatchTables const * patchTables, void * /*deviceContext*/) {
if (patchTables) {
int maxValence = patchTables->GetMaxValence();
GLDrawContext * result = new GLDrawContext(maxValence);
if (result->create(*patchTables)) {
return result;
} else {
delete result;
}
}
return NULL;
}
bool
GLDrawContext::create(Far::PatchTables const & patchTables) {
_isAdaptive = patchTables.IsFeatureAdaptive();
// Process PTable
Far::PatchTables::PatchVertsTable const & ptables = patchTables.GetPatchControlVerticesTable();
glGenBuffers(1, &_patchIndexBuffer);
#if defined(GL_EXT_direct_state_access)
if (glNamedBufferDataEXT) {
glNamedBufferDataEXT(_patchIndexBuffer,
ptables.size() * sizeof(unsigned int), &ptables[0], GL_STATIC_DRAW);
} else {
#else
{
#endif
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);
}
DrawContext::ConvertPatchArrays(patchTables, _patchArrays);
// allocate and initialize additional buffer data
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
// create vertex valence buffer and vertex texture
Far::PatchTables::VertexValenceTable const &
valenceTable = patchTables.GetVertexValenceTable();
if (not valenceTable.empty()) {
_vertexValenceTextureBuffer = createTextureBuffer(valenceTable, GL_R32I);
// also create vertex texture buffer (will be updated in UpdateVertexTexture())
glGenTextures(1, &_vertexTextureBuffer);
}
// create quad offset table buffer
Far::PatchTables::QuadOffsetsTable const &
quadOffsetTable = patchTables.GetQuadOffsetsTable();
if (not quadOffsetTable.empty())
_quadOffsetsTextureBuffer = createTextureBuffer(quadOffsetTable, GL_R32I);
// create ptex coordinate buffer
Far::PatchParamTable const & patchParamTables =
patchTables.GetPatchParamTable();
if (not patchParamTables.empty()) {
if (patchTables.GetSharpnessIndexTable().empty()) {
_patchParamTextureBuffer = createTextureBuffer(patchParamTables, GL_RG32I);
} else {
// if indexed sharpnesses exists, flatten them and interleave into 3-component buffer
std::vector<unsigned int> buffer;
packSharpnessValues(patchTables, buffer);
_patchParamTextureBuffer = createTextureBuffer(buffer, GL_RGB32I);
}
}
glBindBuffer(GL_TEXTURE_BUFFER, 0);
#endif
return true;
}
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
bool
GLDrawContext::SetFVarDataTexture(
Far::PatchTables const & patchTables, int fvarWidth, FVarData const & fvarData,
void * /*deviceContext*/) {
if (not fvarData.empty()) {
FVarData fvarDataTable;
packFVarData(patchTables, fvarWidth, fvarData, fvarDataTable);
_fvarDataTextureBuffer = createTextureBuffer(fvarDataTable, GL_R32F);
return true;
}
return false;
}
#else
bool
GLDrawContext::SetFVarDataTexture(
Far::PatchTables const &, int, FVarData const &,
void * /*deviceContext*/) {
return false;
}
#endif
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
void
GLDrawContext::updateVertexTexture(GLuint vbo)
{
#if defined(GL_EXT_direct_state_access)
if (glTextureBufferEXT) {
glTextureBufferEXT(_vertexTextureBuffer, GL_TEXTURE_BUFFER, GL_R32F, vbo);
} else {
#else
{
#endif
glBindTexture(GL_TEXTURE_BUFFER, _vertexTextureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo);
glBindTexture(GL_TEXTURE_BUFFER, 0);
}
}
#else
void
GLDrawContext::updateVertexTexture(GLuint)
{
}
#endif
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -1,151 +0,0 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_GL_DRAW_CONTEXT_H
#define OPENSUBDIV3_OSD_GL_DRAW_CONTEXT_H
#include "../version.h"
#include <cstddef>
#include "../far/patchTables.h"
#include "../osd/drawContext.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
/// \brief OpenGL specialized DrawContext class
///
/// GLDrawContext 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 GLDrawContext : public DrawContext {
public:
typedef GLuint VertexBufferBinding;
virtual ~GLDrawContext();
/// \brief Create an GLDraContext from Far::PatchTables
///
/// @param patchTables a valid set of Far::PatchTables
///
/// @param deviceContext not used in GLDrawContext
///
static GLDrawContext * Create(Far::PatchTables const * patchTables,
void *deviceContext = NULL);
/// Set vbo as a vertex texture (for gregory patch drawing)
///
/// @param vbo the vertex buffer object to update
///
template<class VERTEX_BUFFER>
void UpdateVertexTexture(VERTEX_BUFFER *vbo, void *deviceContext = NULL) {
(void)(deviceContext); // unused parameter
if (vbo)
updateVertexTexture(vbo->BindVBO());
}
/// Returns the GL texture buffer containing the patch control vertices array
GLuint GetPatchIndexBuffer() const {
return _patchIndexBuffer;
}
/// Returns the GL texture buffer containing the patch local parameterization
/// data
GLuint GetPatchParamTextureBuffer() const {
return _patchParamTextureBuffer;
}
/// Returns the GL texture buffer containing the vertex data
GLuint GetVertexTextureBuffer() const {
return _vertexTextureBuffer;
}
/// Returns the GL texture buffer containing patch vertex valence data (only
/// used by Gregory patches)
GLuint GetVertexValenceTextureBuffer() const {
return _vertexValenceTextureBuffer;
}
/// Returns the GL texture buffer containing patch quad offsets data (only
/// used by Gregory patches)
GLuint GetQuadOffsetsTextureBuffer() const {
return _quadOffsetsTextureBuffer;
}
/// Returns the GL texture buffer containing fvar data
GLuint GetFvarDataTextureBuffer() const {
return _fvarDataTextureBuffer;
}
/// Sets face-varying data buffer
///
/// @param patchTables A valid set of Far::PatchTables
///
/// @param fvarWidth Total face-varying primvar data width in fvarData
///
/// @param fvarData Vector containing the face-varying data
///
/// @param deviceContext (not used)
///
/// @return True if the operation was successful
///
bool SetFVarDataTexture(Far::PatchTables const & patchTables,
int fvarWidth, FVarData const & fvarData,
void *deviceContext = NULL);
protected:
GLuint _patchIndexBuffer;
GLuint _patchParamTextureBuffer;
GLuint _fvarDataTextureBuffer;
GLuint _vertexTextureBuffer;
GLuint _vertexValenceTextureBuffer;
GLuint _quadOffsetsTextureBuffer;
GLDrawContext(int maxValence);
// allocate buffers from patchTables
bool create(Far::PatchTables const & patchTables);
void updateVertexTexture(GLuint vbo);
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_OSD_DRAW_CONTEXT_H */

View File

@ -0,0 +1,106 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glLegacyGregoryPatchTable.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
GLLegacyGregoryPatchTable::GLLegacyGregoryPatchTable() :
_vertexTextureBuffer(0), _vertexValenceTextureBuffer(0),
_quadOffsetsTextureBuffer(0) {
_quadOffsetsBase[0] = _quadOffsetsBase[1] = 0;
}
GLLegacyGregoryPatchTable::~GLLegacyGregoryPatchTable() {
if (_vertexTextureBuffer)
glDeleteTextures(1, &_vertexTextureBuffer);
if (_vertexValenceTextureBuffer)
glDeleteTextures(1, &_vertexValenceTextureBuffer);
if (_quadOffsetsTextureBuffer)
glDeleteTextures(1, &_quadOffsetsTextureBuffer);
}
GLLegacyGregoryPatchTable *
GLLegacyGregoryPatchTable::Create(Far::PatchTables const *farPatchTables) {
GLLegacyGregoryPatchTable *result = new GLLegacyGregoryPatchTable();
glGenTextures(1, &result->_vertexTextureBuffer);
glGenTextures(1, &result->_vertexValenceTextureBuffer);
glGenTextures(1, &result->_quadOffsetsTextureBuffer);
Far::PatchTables::VertexValenceTable const &
valenceTable = farPatchTables->GetVertexValenceTable();
Far::PatchTables::QuadOffsetsTable const &
quadOffsetsTable = farPatchTables->GetQuadOffsetsTable();
GLuint buffers[2];
glGenBuffers(2, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, valenceTable.size() * sizeof(int),
&valenceTable[0], GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, result->_vertexValenceTextureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffers[0]);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ARRAY_BUFFER, quadOffsetsTable.size() * sizeof(int),
&quadOffsetsTable[0], GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, result->_quadOffsetsTextureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffers[1]);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(2, buffers);
result->_quadOffsetsBase[0] = 0;
result->_quadOffsetsBase[1] = 0;
// scan patchtable to find quadOffsetsBase.
for (int i = 0; i < farPatchTables->GetNumPatchArrays(); ++i) {
// GREGORY_BOUNDARY's quadoffsets come after GREGORY's.
if (farPatchTables->GetPatchArrayDescriptor(i) ==
Far::PatchDescriptor::GREGORY) {
result->_quadOffsetsBase[1] = farPatchTables->GetNumPatches(i) * 4;
break;
}
}
return result;
}
void
GLLegacyGregoryPatchTable::UpdateVertexBuffer(GLuint vbo) {
glBindTexture(GL_TEXTURE_BUFFER, _vertexTextureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo);
glBindTexture(GL_TEXTURE_BUFFER, 0);
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,86 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H
#define OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H
#include "../version.h"
#include "../far/patchTables.h"
#include "../osd/nonCopyable.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
class GLLegacyGregoryPatchTable
: private NonCopyable<GLLegacyGregoryPatchTable> {
public:
~GLLegacyGregoryPatchTable();
static GLLegacyGregoryPatchTable *Create(Far::PatchTables const *patchTable);
void UpdateVertexBuffer(GLuint vbo);
GLuint GetVertexTextureBuffer() const {
return _vertexTextureBuffer;
}
GLuint GetVertexValenceTextureBuffer() const {
return _vertexValenceTextureBuffer;
}
GLuint GetQuadOffsetsTextureBuffer() const {
return _quadOffsetsTextureBuffer;
}
GLuint GetQuadOffsetsBase(Far::PatchDescriptor::Type type) {
if (type == Far::PatchDescriptor::GREGORY_BOUNDARY) {
return _quadOffsetsBase[1];
}
return _quadOffsetsBase[0];
}
protected:
GLLegacyGregoryPatchTable();
private:
GLuint _vertexTextureBuffer;
GLuint _vertexValenceTextureBuffer;
GLuint _quadOffsetsTextureBuffer;
GLuint _quadOffsetsBase[2]; // gregory, boundaryGregory
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_GL_LEGACY_GREGORY_PATCH_TABLE_H

View File

@ -28,14 +28,15 @@
#include "../version.h"
#include "../osd/mesh.h"
#include "../osd/glDrawContext.h"
#include "../osd/glPatchTable.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
typedef MeshInterface<GLDrawContext> GLMeshInterface;
typedef MeshInterface<GLPatchTable> GLMeshInterface;
} // end namespace Osd

View File

@ -0,0 +1,141 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include "../osd/glPatchTable.h"
#include "../far/patchTables.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Osd {
GLPatchTable::GLPatchTable() :
_indexBuffer(0), _patchParamTexture(0) {
}
GLPatchTable::~GLPatchTable() {
if (_indexBuffer) glDeleteBuffers(1, &_indexBuffer);
if (_patchParamTexture) glDeleteTextures(1, &_patchParamTexture);
}
GLPatchTable *
GLPatchTable::Create(Far::PatchTables const *farPatchTables,
void * /*deviceContext*/) {
GLPatchTable *instance = new GLPatchTable();
if (instance->allocate(farPatchTables)) return instance;
delete instance;
return 0;
}
bool
GLPatchTable::allocate(Far::PatchTables const *farPatchTables) {
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
std::vector<int> buffer;
std::vector<unsigned int> ppBuffer;
// needs reserve?
int nPatchArrays = farPatchTables->GetNumPatchArrays();
// for each patchArray
for (int j = 0; j < nPatchArrays; ++j) {
PatchArray patchArray(farPatchTables->GetPatchArrayDescriptor(j),
farPatchTables->GetNumPatches(j),
(int)buffer.size(),
(int)ppBuffer.size()/3);
_patchArrays.push_back(patchArray);
// indices
Far::ConstIndexArray indices = farPatchTables->GetPatchArrayVertices(j);
for (int k = 0; k < indices.size(); ++k) {
buffer.push_back(indices[k]);
}
// patchParams
#if 0
// XXX: we need sharpness interface for patcharray or put sharpness
// into patchParam.
Far::ConstPatchParamArray patchParams =
farPatchTables->GetPatchParams(j);
for (int k = 0; k < patchParams.size(); ++k) {
float sharpness = 0.0;
ppBuffer.push_back(patchParams[k].faceIndex);
ppBuffer.push_back(patchParams[k].bitField.field);
ppBuffer.push_back(*((unsigned int *)&sharpness));
}
#else
// XXX: workaround. GetPatchParamTable() will be deprecated though.
Far::PatchParamTable const & patchParamTables =
farPatchTables->GetPatchParamTable();
std::vector<Far::Index> const &sharpnessIndexTable =
farPatchTables->GetSharpnessIndexTable();
int numPatches = farPatchTables->GetNumPatches(j);
for (int k = 0; k < numPatches; ++k) {
float sharpness = 0.0;
int patchIndex = (int)ppBuffer.size()/3;
if (patchIndex < (int)sharpnessIndexTable.size()) {
int sharpnessIndex = sharpnessIndexTable[patchIndex];
if (sharpnessIndex >= 0)
sharpness = farPatchTables->GetSharpnessValues()[sharpnessIndex];
}
ppBuffer.push_back(patchParamTables[patchIndex].faceIndex);
ppBuffer.push_back(patchParamTables[patchIndex].bitField.field);
ppBuffer.push_back(*((unsigned int *)&sharpness));
}
#endif
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
(int)buffer.size()*sizeof(int), &buffer[0], GL_STATIC_DRAW);
// patchParam is currently expected to be texture (it can be SSBO)
GLuint texBuffer = 0;
glGenBuffers(1, &texBuffer);
glBindBuffer(GL_ARRAY_BUFFER, texBuffer);
glBufferData(GL_ARRAY_BUFFER, ppBuffer.size()*sizeof(unsigned int),
&ppBuffer[0], GL_STATIC_DRAW);
glGenTextures(1, &_patchParamTexture);
glBindTexture(GL_TEXTURE_BUFFER, _patchParamTexture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32I, texBuffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glDeleteBuffers(1, &texBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -0,0 +1,112 @@
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_GL_PATCH_TABLE_H
#define OPENSUBDIV3_OSD_GL_PATCH_TABLE_H
#include "../version.h"
#include <vector>
#include "../far/patchDescriptor.h"
#include "../osd/nonCopyable.h"
#include "../osd/opengl.h"
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far{
class PatchTables;
};
namespace Osd {
class GLPatchTable : private NonCopyable<GLPatchTable> {
public:
typedef GLuint VertexBufferBinding;
// XXX: this struct will be further refactored.
class PatchArray {
public:
PatchArray(Far::PatchDescriptor desc, int numPatches,
int indexBase, int primitiveIdBase) :
desc(desc), numPatches(numPatches), indexBase(indexBase),
primitiveIdBase(primitiveIdBase) {}
Far::PatchDescriptor const &GetDescriptor() const {
return desc;
}
int GetNumPatches() const {
return numPatches;
}
int GetIndexBase() const {
return indexBase;
}
int GetPrimitiveIdBase() const {
return primitiveIdBase;
}
private:
Far::PatchDescriptor desc;
int numPatches;
int indexBase; // an offset within the index buffer
int primitiveIdBase; // an offset within the patch param buffer
};
typedef std::vector<PatchArray> PatchArrayVector;
GLPatchTable();
~GLPatchTable();
static GLPatchTable *Create(Far::PatchTables const *farPatchTables,
void *deviceContext = NULL);
PatchArrayVector const &GetPatchArrays() const {
return _patchArrays;
}
/// Returns the GL index buffer containing the patch control vertices
GLuint GetPatchIndexBuffer() const {
return _indexBuffer;
}
/// Returns the GL texture buffer containing the patch parameter
GLuint GetPatchParamTextureBuffer() const {
return _patchParamTexture;
}
protected:
// allocate buffers from patchTables
bool allocate(Far::PatchTables const *farPatchTables);
PatchArrayVector _patchArrays;
GLuint _indexBuffer;
GLuint _patchParamTexture;
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_GL_PATCH_TABLE_H

View File

@ -127,9 +127,9 @@ int OsdPrimitiveIdBase();
//
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
Buffer<uint3> OsdPatchParamBuffer : register( t3 );
Buffer<uint3> OsdPatchParamBuffer : register( t0 );
#else
Buffer<uint2> OsdPatchParamBuffer : register( t3 );
Buffer<uint2> OsdPatchParamBuffer : register( t0 );
#endif
int OsdGetPatchIndex(int primitiveId)

View File

@ -64,8 +64,8 @@ float sinfn(uint n, uint j) {
// Patches.TessVertexGregory
//----------------------------------------------------------
Buffer<float> VertexBuffer : register( t0 );
Buffer<int> OsdValenceBuffer : register( t1 );
Buffer<float> VertexBuffer : register( t2 );
Buffer<int> OsdValenceBuffer : register( t3 );
void vs_main_patches( in InputVertex input,
uint vID : SV_VertexID,
@ -260,7 +260,7 @@ void vs_main_patches( in InputVertex input,
// Patches.HullGregory
//----------------------------------------------------------
Buffer<int> OsdQuadOffsetBuffer : register( t2 );
Buffer<int> OsdQuadOffsetBuffer : register( t4 );
HS_CONSTANT_FUNC_OUT HSConstFunc(
InputPatch<GregHullVertex, 4> patch,

View File

@ -60,11 +60,11 @@ typedef std::bitset<NUM_MESH_BITS> MeshBitset;
// ---------------------------------------------------------------------------
template <class DRAW_CONTEXT>
template <class PATCH_TABLE>
class MeshInterface {
public:
typedef DRAW_CONTEXT DrawContext;
typedef typename DrawContext::VertexBufferBinding VertexBufferBinding;
typedef PATCH_TABLE PatchTable;
typedef typename PatchTable::VertexBufferBinding VertexBufferBinding;
public:
MeshInterface() { }
@ -73,6 +73,8 @@ public:
virtual int GetNumVertices() const = 0;
virtual int GetMaxValence() const = 0;
virtual void UpdateVertexBuffer(float const *vertexData,
int startVertex, int numVerts) = 0;
@ -83,15 +85,14 @@ public:
virtual void Synchronize() = 0;
virtual DrawContext * GetDrawContext() = 0;
virtual PatchTable * GetPatchTable() const = 0;
virtual Far::PatchTables const *GetFarPatchTables() const = 0;
virtual VertexBufferBinding BindVertexBuffer() = 0;
virtual VertexBufferBinding BindVaryingBuffer() = 0;
virtual void SetFVarDataChannel(int fvarWidth,
std::vector<float> const & fvarData) = 0;
protected:
static inline void refineMesh(Far::TopologyRefiner & refiner,
int level, bool adaptive,
@ -232,17 +233,17 @@ static EVALUATOR *GetEvaluator(
template <typename VERTEX_BUFFER,
typename STENCIL_TABLES,
typename EVALUATOR,
typename DRAW_CONTEXT,
typename PATCH_TABLE,
typename DEVICE_CONTEXT = void>
class Mesh : public MeshInterface<DRAW_CONTEXT> {
class Mesh : public MeshInterface<PATCH_TABLE> {
public:
typedef VERTEX_BUFFER VertexBuffer;
typedef EVALUATOR Evaluator;
typedef STENCIL_TABLES StencilTables;
typedef DRAW_CONTEXT DrawContext;
typedef PATCH_TABLE PatchTable;
typedef DEVICE_CONTEXT DeviceContext;
typedef EvaluatorCacheT<Evaluator> EvaluatorCache;
typedef typename DrawContext::VertexBufferBinding VertexBufferBinding;
typedef typename PatchTable::VertexBufferBinding VertexBufferBinding;
Mesh(Far::TopologyRefiner * refiner,
int numVertexElements,
@ -253,19 +254,20 @@ public:
DeviceContext * deviceContext = NULL) :
_refiner(refiner),
_patchTables(NULL),
_farPatchTables(NULL),
_numVertices(0),
_maxValence(0),
_vertexBuffer(NULL),
_varyingBuffer(NULL),
_vertexStencilTables(NULL),
_varyingStencilTables(NULL),
_evaluatorCache(evaluatorCache),
_drawContext(NULL),
_patchTable(NULL),
_deviceContext(deviceContext) {
assert(_refiner);
MeshInterface<DRAW_CONTEXT>::refineMesh(
MeshInterface<PATCH_TABLE>::refineMesh(
*_refiner, level,
bits.test(MeshAdaptive),
bits.test(MeshUseSingleCreasePatch));
@ -296,21 +298,16 @@ public:
numVaryingElements,
varyingBufferStride);
}
// will retire
_drawContext->UpdateVertexTexture(_vertexBuffer, _deviceContext);
}
virtual ~Mesh() {
delete _refiner;
delete _patchTables;
delete _farPatchTables;
delete _vertexBuffer;
delete _varyingBuffer;
delete _vertexStencilTables;
delete _varyingStencilTables;
delete _drawContext;
delete _patchTable;
// deviceContext and evaluatorCache are not owned by this class.
}
@ -373,23 +370,18 @@ public:
Evaluator::Synchronize(_deviceContext);
}
virtual DrawContext * GetDrawContext() {
return _drawContext;
virtual PatchTable * GetPatchTable() const {
return _patchTable;
}
virtual void SetFVarDataChannel(int fvarWidth,
std::vector<float> const & fvarData) {
if (_patchTables and
_drawContext and
fvarWidth and
(not fvarData.empty())) {
_drawContext->SetFVarDataTexture(*_patchTables, fvarWidth, fvarData,
_deviceContext);
}
virtual Far::PatchTables const *GetFarPatchTables() const {
return _farPatchTables;
}
virtual int GetNumVertices() const { return _numVertices; }
virtual int GetMaxValence() const { return _maxValence; }
virtual VertexBufferBinding BindVertexBuffer() {
return _vertexBuffer->BindVBO(_deviceContext);
}
@ -457,16 +449,16 @@ private:
Far::PatchTablesFactory::Options::ENDCAP_LEGACY_GREGORY);
}
_patchTables = Far::PatchTablesFactory::Create(*_refiner, poptions);
_farPatchTables = Far::PatchTablesFactory::Create(*_refiner, poptions);
// if there's endcap stencils, merge it into regular stencils.
if (_patchTables->GetEndCapVertexStencilTables()) {
if (_farPatchTables->GetEndCapVertexStencilTables()) {
// append stencils
if (Far::StencilTables const *vertexStencilsWithEndCap =
Far::StencilTablesFactory::AppendEndCapStencilTables(
*_refiner,
vertexStencils,
_patchTables->GetEndCapVertexStencilTables())) {
_farPatchTables->GetEndCapVertexStencilTables())) {
delete vertexStencils;
vertexStencils = vertexStencilsWithEndCap;
}
@ -475,14 +467,15 @@ private:
Far::StencilTablesFactory::AppendEndCapStencilTables(
*_refiner,
varyingStencils,
_patchTables->GetEndCapVaryingStencilTables())) {
_farPatchTables->GetEndCapVaryingStencilTables())) {
delete varyingStencils;
varyingStencils = varyingStencilsWithEndCap;
}
}
}
_drawContext = DrawContext::Create(_patchTables, _deviceContext);
_maxValence = _farPatchTables->GetMaxValence();
_patchTable = PatchTable::Create(_farPatchTables, _deviceContext);
// numvertices = coarse verts + refined verts + gregory basis verts
_numVertices = vertexStencils->GetNumControlVertices()
@ -517,9 +510,10 @@ private:
}
Far::TopologyRefiner * _refiner;
Far::PatchTables * _patchTables;
Far::PatchTables * _farPatchTables;
int _numVertices;
int _maxValence;
VertexBuffer * _vertexBuffer;
VertexBuffer * _varyingBuffer;
@ -531,7 +525,7 @@ private:
StencilTables const * _varyingStencilTables;
EvaluatorCache * _evaluatorCache;
DrawContext *_drawContext;
PatchTable *_patchTable;
DeviceContext *_deviceContext;
};