diff --git a/examples/common/patchColors.h b/examples/common/patchColors.h index 7a16c3cd..c9a07edb 100644 --- a/examples/common/patchColors.h +++ b/examples/common/patchColors.h @@ -22,10 +22,8 @@ // language governing permissions and limitations under the Apache License. // -#ifndef COMMON_PATCH_COLORS_H -#define COMMON_PATCH_COLORS_H - -#include +#ifndef OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H +#define OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H #include @@ -33,4 +31,4 @@ float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchDescriptor const & desc); -#endif /* COMMON_PATCH_COLORS_H */ +#endif /* OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H */ diff --git a/examples/dxPtexViewer/dxPtexViewer.cpp b/examples/dxPtexViewer/dxPtexViewer.cpp index a5a86026..dec13cc4 100755 --- a/examples/dxPtexViewer/dxPtexViewer.cpp +++ b/examples/dxPtexViewer/dxPtexViewer.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -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( refiner, numVertexElements, @@ -753,7 +748,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -765,7 +760,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -778,7 +773,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -792,7 +787,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -804,7 +799,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new Osd::Mesh( 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(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 diff --git a/examples/dxPtexViewer/shader.hlsl b/examples/dxPtexViewer/shader.hlsl index 7774a92b..18d3a73d 100644 --- a/examples/dxPtexViewer/shader.hlsl +++ b/examples/dxPtexViewer/shader.hlsl @@ -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() { diff --git a/examples/dxViewer/dxviewer.cpp b/examples/dxViewer/dxviewer.cpp index d4c583ab..e5b643c8 100644 --- a/examples/dxViewer/dxviewer.cpp +++ b/examples/dxViewer/dxviewer.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -57,7 +56,9 @@ #include #include -OpenSubdiv::Osd::D3D11MeshInterface *g_mesh; +#include +OpenSubdiv::Osd::D3D11MeshInterface *g_mesh = NULL; +OpenSubdiv::Osd::D3D11LegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL; #include #include "../common/stopwatch.h" @@ -321,7 +322,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -333,7 +334,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -345,7 +346,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -358,7 +359,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -372,7 +373,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -384,7 +385,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( 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(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; diff --git a/examples/glEvalLimit/glEvalLimit.cpp b/examples/glEvalLimit/glEvalLimit.cpp index 8c21f6d0..0e9beb31 100755 --- a/examples/glEvalLimit/glEvalLimit.cpp +++ b/examples/glEvalLimit/glEvalLimit.cpp @@ -45,7 +45,6 @@ GLFWmonitor* g_primary=0; #include #include #include -#include #include #include diff --git a/examples/glFVarViewer/glFVarViewer.cpp b/examples/glFVarViewer/glFVarViewer.cpp index 0ea0dcd9..433f5386 100644 --- a/examples/glFVarViewer/glFVarViewer.cpp +++ b/examples/glFVarViewer/glFVarViewer.cpp @@ -42,7 +42,6 @@ GLFWwindow* g_window = 0; GLFWmonitor* g_primary = 0; -#include #include #include @@ -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 const & fvarSrcData) { + Release(); + OpenSubdiv::Far::ConstIndexArray indices = + patchTables->GetFVarPatchesValues(0); + + // expand fvardata to per-patch array + std::vector 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::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); diff --git a/examples/glImaging/glImaging.cpp b/examples/glImaging/glImaging.cpp index 805eb378..f145db90 100755 --- a/examples/glImaging/glImaging.cpp +++ b/examples/glImaging/glImaging.cpp @@ -82,7 +82,6 @@ #include #endif -#include #include #include @@ -235,7 +234,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -245,7 +244,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -256,7 +255,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -267,7 +266,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( refiner, numVertexElements, @@ -281,7 +280,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -292,7 +291,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -303,7 +302,7 @@ createOsdMesh(std::string const &kernel, return new Osd::Mesh( + 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); diff --git a/examples/glPaintTest/glPaintTest.cpp b/examples/glPaintTest/glPaintTest.cpp index 65761066..57f41a19 100644 --- a/examples/glPaintTest/glPaintTest.cpp +++ b/examples/glPaintTest/glPaintTest.cpp @@ -42,7 +42,6 @@ GLFWwindow* g_window=0; GLFWmonitor* g_primary=0; -#include #include #include @@ -241,7 +240,7 @@ createOsdMesh() { g_mesh = new OpenSubdiv::Osd::Mesh( + 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); diff --git a/examples/glPtexViewer/glPtexViewer.cpp b/examples/glPtexViewer/glPtexViewer.cpp index b8f22071..1e572dbc 100644 --- a/examples/glPtexViewer/glPtexViewer.cpp +++ b/examples/glPtexViewer/glPtexViewer.cpp @@ -49,8 +49,6 @@ GLFWmonitor* g_primary = 0; #include #include #include - -#include #include #include @@ -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::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -958,7 +947,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -969,7 +958,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -981,7 +970,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( refiner, numVertexElements, @@ -995,7 +984,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -1007,7 +996,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + OpenSubdiv::Osd::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -1020,7 +1009,7 @@ createOsdMesh(int level, int kernel) { g_mesh = new OpenSubdiv::Osd::Mesh( + 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); diff --git a/examples/glViewer/glViewer.cpp b/examples/glViewer/glViewer.cpp index 19c7c318..7e1243ec 100644 --- a/examples/glViewer/glViewer.cpp +++ b/examples/glViewer/glViewer.cpp @@ -43,7 +43,6 @@ GLFWwindow* g_window=0; GLFWmonitor* g_primary=0; #include -#include #include #include @@ -83,7 +82,9 @@ GLFWmonitor* g_primary=0; #endif #include -OpenSubdiv::Osd::GLMeshInterface *g_mesh; +#include +OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL; +OpenSubdiv::Osd::GLLegacyGregoryPatchTable *g_legacyGregoryPatchTable = NULL; #include #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 const & fvarSrcData) { + Release(); + OpenSubdiv::Far::ConstIndexArray indices = + patchTables->GetFVarPatchesValues(0); + + // expand fvardata to per-patch array + std::vector 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::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -542,7 +592,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + 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::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -566,7 +616,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( refiner, numVertexElements, @@ -580,7 +630,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + 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::GLPatchTable>( refiner, numVertexElements, numVaryingElements, @@ -605,7 +655,7 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme= g_mesh = new Osd::Mesh( + 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; + } //------------------------------------------------------------------------------ diff --git a/opensubdiv/osd/CMakeLists.txt b/opensubdiv/osd/CMakeLists.txt index 775c155b..4994ef64 100644 --- a/opensubdiv/osd/CMakeLists.txt +++ b/opensubdiv/osd/CMakeLists.txt @@ -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 ) diff --git a/opensubdiv/osd/d3d11DrawContext.cpp b/opensubdiv/osd/d3d11DrawContext.cpp deleted file mode 100644 index d657147f..00000000 --- a/opensubdiv/osd/d3d11DrawContext.cpp +++ /dev/null @@ -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 - -#include - -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(&patchParamTables[0]); - - std::vector 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 diff --git a/opensubdiv/osd/d3d11DrawContext.h b/opensubdiv/osd/d3d11DrawContext.h deleted file mode 100644 index 87ad9702..00000000 --- a/opensubdiv/osd/d3d11DrawContext.h +++ /dev/null @@ -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 - -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 - 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 - 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 - 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 - 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 */ diff --git a/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp new file mode 100644 index 00000000..06b21fc6 --- /dev/null +++ b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.cpp @@ -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 + +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 diff --git a/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h new file mode 100644 index 00000000..fdd16992 --- /dev/null +++ b/opensubdiv/osd/d3d11LegacyGregoryPatchTable.h @@ -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 { +public: + ~D3D11LegacyGregoryPatchTable(); + + template + 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 diff --git a/opensubdiv/osd/d3d11Mesh.h b/opensubdiv/osd/d3d11Mesh.h index 550fd51a..5ce0a7f5 100644 --- a/opensubdiv/osd/d3d11Mesh.h +++ b/opensubdiv/osd/d3d11Mesh.h @@ -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 D3D11MeshInterface; +typedef MeshInterface D3D11MeshInterface; + } // end namespace Osd diff --git a/opensubdiv/osd/d3d11PatchTable.cpp b/opensubdiv/osd/d3d11PatchTable.cpp new file mode 100644 index 00000000..cb886668 --- /dev/null +++ b/opensubdiv/osd/d3d11PatchTable.cpp @@ -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 +#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 buffer; + std::vector 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 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 + diff --git a/opensubdiv/osd/d3d11PatchTable.h b/opensubdiv/osd/d3d11PatchTable.h new file mode 100644 index 00000000..604f7404 --- /dev/null +++ b/opensubdiv/osd/d3d11PatchTable.h @@ -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 +#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 { +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 PatchArrayVector; + + D3D11PatchTable(); + ~D3D11PatchTable(); + + template + 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 diff --git a/opensubdiv/osd/drawContext.cpp b/opensubdiv/osd/drawContext.cpp deleted file mode 100644 index d274a39e..00000000 --- a/opensubdiv/osd/drawContext.cpp +++ /dev/null @@ -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 - -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 & dst) { - - dst.resize(patchTables.GetNumControlVerticesTotal()); - Index * ptr = &dst[0]; - - int narrays = patchTables.GetNumPatchArrays(); - for (int array=0; array & dst) { - - Far::PatchParamTable const & patchParamTables = - patchTables.GetPatchParamTable(); - - std::vector const &sharpnessIndexTable = - patchTables.GetSharpnessIndexTable(); - - std::vector 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 diff --git a/opensubdiv/osd/drawContext.h b/opensubdiv/osd/drawContext.h deleted file mode 100644 index 923eb0ab..00000000 --- a/opensubdiv/osd/drawContext.h +++ /dev/null @@ -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 -#include - -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 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 FVarData; - - -protected: - - static void packPatchVerts(Far::PatchTables const & patchTables, - std::vector & dst); - - static void packSharpnessValues(Far::PatchTables const & patchTables, - std::vector & 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 */ diff --git a/opensubdiv/osd/glDrawContext.cpp b/opensubdiv/osd/glDrawContext.cpp deleted file mode 100644 index afef5b43..00000000 --- a/opensubdiv/osd/glDrawContext.cpp +++ /dev/null @@ -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 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 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 diff --git a/opensubdiv/osd/glDrawContext.h b/opensubdiv/osd/glDrawContext.h deleted file mode 100644 index eeafecec..00000000 --- a/opensubdiv/osd/glDrawContext.h +++ /dev/null @@ -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 - -#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 - 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 */ diff --git a/opensubdiv/osd/glLegacyGregoryPatchTable.cpp b/opensubdiv/osd/glLegacyGregoryPatchTable.cpp new file mode 100644 index 00000000..6e139fa3 --- /dev/null +++ b/opensubdiv/osd/glLegacyGregoryPatchTable.cpp @@ -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 diff --git a/opensubdiv/osd/glLegacyGregoryPatchTable.h b/opensubdiv/osd/glLegacyGregoryPatchTable.h new file mode 100644 index 00000000..221f6667 --- /dev/null +++ b/opensubdiv/osd/glLegacyGregoryPatchTable.h @@ -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 { +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 diff --git a/opensubdiv/osd/glMesh.h b/opensubdiv/osd/glMesh.h index cdb6667f..3237e353 100644 --- a/opensubdiv/osd/glMesh.h +++ b/opensubdiv/osd/glMesh.h @@ -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 GLMeshInterface; +typedef MeshInterface GLMeshInterface; + } // end namespace Osd diff --git a/opensubdiv/osd/glPatchTable.cpp b/opensubdiv/osd/glPatchTable.cpp new file mode 100644 index 00000000..27f12ce2 --- /dev/null +++ b/opensubdiv/osd/glPatchTable.cpp @@ -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 buffer; + std::vector 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 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 + diff --git a/opensubdiv/osd/glPatchTable.h b/opensubdiv/osd/glPatchTable.h new file mode 100644 index 00000000..43656ca8 --- /dev/null +++ b/opensubdiv/osd/glPatchTable.h @@ -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 +#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 { +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 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 diff --git a/opensubdiv/osd/hlslPatchCommon.hlsl b/opensubdiv/osd/hlslPatchCommon.hlsl index 1cfb255a..cda8b4d3 100644 --- a/opensubdiv/osd/hlslPatchCommon.hlsl +++ b/opensubdiv/osd/hlslPatchCommon.hlsl @@ -127,9 +127,9 @@ int OsdPrimitiveIdBase(); // #if defined OSD_PATCH_ENABLE_SINGLE_CREASE - Buffer OsdPatchParamBuffer : register( t3 ); + Buffer OsdPatchParamBuffer : register( t0 ); #else - Buffer OsdPatchParamBuffer : register( t3 ); + Buffer OsdPatchParamBuffer : register( t0 ); #endif int OsdGetPatchIndex(int primitiveId) diff --git a/opensubdiv/osd/hlslPatchGregory.hlsl b/opensubdiv/osd/hlslPatchGregory.hlsl index ac322ef9..657bcd1d 100644 --- a/opensubdiv/osd/hlslPatchGregory.hlsl +++ b/opensubdiv/osd/hlslPatchGregory.hlsl @@ -64,8 +64,8 @@ float sinfn(uint n, uint j) { // Patches.TessVertexGregory //---------------------------------------------------------- -Buffer VertexBuffer : register( t0 ); -Buffer OsdValenceBuffer : register( t1 ); +Buffer VertexBuffer : register( t2 ); +Buffer 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 OsdQuadOffsetBuffer : register( t2 ); +Buffer OsdQuadOffsetBuffer : register( t4 ); HS_CONSTANT_FUNC_OUT HSConstFunc( InputPatch patch, diff --git a/opensubdiv/osd/mesh.h b/opensubdiv/osd/mesh.h index d9da0079..107b1f98 100644 --- a/opensubdiv/osd/mesh.h +++ b/opensubdiv/osd/mesh.h @@ -60,11 +60,11 @@ typedef std::bitset MeshBitset; // --------------------------------------------------------------------------- -template +template 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 const & fvarData) = 0; - protected: static inline void refineMesh(Far::TopologyRefiner & refiner, int level, bool adaptive, @@ -232,17 +233,17 @@ static EVALUATOR *GetEvaluator( template -class Mesh : public MeshInterface { +class Mesh : public MeshInterface { 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 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::refineMesh( + MeshInterface::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 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; };