Merge pull request #503 from takahito-tejima/refactor

osd layer: Add GLPatchTable and retire DrawContext
This commit is contained in:
David G Yu 2015-05-20 18:22:42 -07:00
commit 70e6148a4d
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;
};