diff --git a/examples/mayaViewer/OpenSubdivShader.cpp b/examples/mayaViewer/OpenSubdivShader.cpp index a38aa34e..d59f253f 100644 --- a/examples/mayaViewer/OpenSubdivShader.cpp +++ b/examples/mayaViewer/OpenSubdivShader.cpp @@ -131,13 +131,11 @@ static const char *defaultShaderSource = // Draw styles for EffectDrawRegistry enum Effect { - kQuadFill = 0, - kQuadLine = 1, - kTriFill = 2, - kTriLine = 3, - kPoint = 4, + kFill = 0, + kLine = 1, + kPoint = 2, }; -typedef std::pair EffectDesc; +typedef std::pair EffectDesc; // #### Override of OpenSubdiv::OsdGLDrawRegistry // @@ -214,17 +212,20 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc) SourceConfigType * sconfig = BaseRegistry::_CreateDrawSourceConfig(desc.first); - if (desc.first.type != OpenSubdiv::kNonPatch) { - // Per-vertex descriptors are use for uniform refinement - if (effect == kQuadFill) effect = kTriFill; - if (effect == kQuadLine) effect = kTriLine; - sconfig->geometryShader.AddDefine("SMOOTH_NORMALS"); - - } else { + bool quad = false; + if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS) { // Configuration for adaptive refinement sconfig->vertexShader.version = "#version 410\n"; sconfig->vertexShader.source = _shaderSource; sconfig->vertexShader.AddDefine("VERTEX_SHADER"); + quad = true; + } else if (desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) { + sconfig->vertexShader.version = "#version 410\n"; + sconfig->vertexShader.source = _shaderSource; + sconfig->vertexShader.AddDefine("VERTEX_SHADER"); + } else { + // adaptive patches + sconfig->geometryShader.AddDefine("SMOOTH_NORMALS"); } assert(sconfig); @@ -254,29 +255,20 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc) sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER"); // Set up directives according to draw style + if (quad) { + sconfig->geometryShader.AddDefine("PRIM_QUAD"); + sconfig->fragmentShader.AddDefine("PRIM_QUAD"); + } else { + sconfig->geometryShader.AddDefine("PRIM_TRI"); + sconfig->fragmentShader.AddDefine("PRIM_TRI"); + } switch (effect) { - case kQuadFill: - sconfig->geometryShader.AddDefine("PRIM_QUAD"); + case kFill: sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL"); - sconfig->fragmentShader.AddDefine("PRIM_QUAD"); sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL"); break; - case kQuadLine: - sconfig->geometryShader.AddDefine("PRIM_QUAD"); + case kLine: sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE"); - sconfig->fragmentShader.AddDefine("PRIM_QUAD"); - sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE"); - break; - case kTriFill: - sconfig->geometryShader.AddDefine("PRIM_TRI"); - sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL"); - sconfig->fragmentShader.AddDefine("PRIM_TRI"); - sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL"); - break; - case kTriLine: - sconfig->geometryShader.AddDefine("PRIM_TRI"); - sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE"); - sconfig->fragmentShader.AddDefine("PRIM_TRI"); sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE"); break; case kPoint: @@ -344,7 +336,7 @@ EffectDrawRegistry::_CreateDrawConfig( if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) { glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2 } - if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) { + if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) { glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3 } if ((loc = glGetUniformLocation(config->program, "g_uvFVarBuffer")) != -1) { @@ -668,31 +660,36 @@ OpenSubdivShader::draw(const MHWRender::MDrawContext &mDrawContext, glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); glEnableVertexAttribArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->patchIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, osdDrawContext->GetPatchIndexBuffer()); // Get list of patches from OSD - OpenSubdiv::OsdPatchArrayVector const & patches = + OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = osdDrawContext->patchArrays; // Draw patches for (size_t i = 0; i < patches.size(); ++i) { - OpenSubdiv::OsdPatchArray const & patch = patches[i]; + OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i]; - bindProgram(mDrawContext, osdDrawContext, patch); + GLuint program = bindProgram(mDrawContext, osdDrawContext, patch); - if (patch.desc.type != OpenSubdiv::kNonPatch) { - glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize()); + GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase"); + GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase"); + glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex()); + glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex()); - glDrawElements(GL_PATCHES, - patch.numIndices, GL_UNSIGNED_INT, - reinterpret_cast(patch.firstIndex * - sizeof(unsigned int))); - } else { - glDrawElements(_scheme == OsdMeshData::kLoop ? GL_TRIANGLES : GL_LINES_ADJACENCY, - patch.numIndices, GL_UNSIGNED_INT, - reinterpret_cast(patch.firstIndex * - sizeof(unsigned int))); + GLenum primType = GL_PATCHES; + if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::QUADS) { + primType = GL_LINES_ADJACENCY; + } else if (patch.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) { + primType = GL_TRIANGLES; + } else if (patch.GetDescriptor().GetType() >= OpenSubdiv::FarPatchTables::REGULAR) { + glPatchParameteri(GL_PATCH_VERTICES, patch.GetDescriptor().GetNumControlVertices()); } + glDrawElements(primType, + patch.GetNumIndices(), GL_UNSIGNED_INT, + reinterpret_cast(patch.GetVertIndex() * + sizeof(unsigned int))); + CHECK_GL_ERROR("post draw\n"); } @@ -782,14 +779,14 @@ OpenSubdivShader::updateRegistry() GLuint OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext, OpenSubdiv::OsdGLDrawContext *osdDrawContext, - const OpenSubdiv::OsdPatchArray & patch) + const OpenSubdiv::OsdDrawContext::PatchArray & patch) { CHECK_GL_ERROR("bindProgram begin\n"); // Primitives are triangles for Loop subdivision, quads otherwise - Effect effect = (_scheme == OsdMeshData::kLoop) ? kTriFill : kQuadFill; - EffectDesc effectDesc( patch.desc, effect ); + Effect effect = kFill; + EffectDesc effectDesc( patch.GetDescriptor(), effect ); // Build shader EffectDrawRegistry::ConfigType * @@ -828,13 +825,9 @@ OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext, // Update and bind tessellation state struct Tessellation { float TessLevel; - int GregoryQuadOffsetBase; - int LevelBase; } tessellationData; tessellationData.TessLevel = static_cast(1 << _tessFactor); - tessellationData.GregoryQuadOffsetBase = patch.gregoryQuadOffsetBase; - tessellationData.LevelBase = patch.levelBase; if (!g_tessellationUB) { glGenBuffers(1, &g_tessellationUB); @@ -932,30 +925,30 @@ OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext, // GL texture buffers. These are managed by the DrawContext // and must be bound for use by the program in addition to // any buffers used by the client/application shading code. - if (osdDrawContext->vertexTextureBuffer) { + if (osdDrawContext->GetVertexTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, - osdDrawContext->vertexTextureBuffer); + osdDrawContext->GetVertexTextureBuffer()); } - if (osdDrawContext->vertexValenceTextureBuffer) { + if (osdDrawContext->GetVertexValenceTextureBuffer()) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_BUFFER, - osdDrawContext->vertexValenceTextureBuffer); + osdDrawContext->GetVertexValenceTextureBuffer()); } - if (osdDrawContext->quadOffsetTextureBuffer) { + if (osdDrawContext->GetQuadOffsetsTextureBuffer()) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_BUFFER, - osdDrawContext->quadOffsetTextureBuffer); + osdDrawContext->GetQuadOffsetsTextureBuffer()); } - if (osdDrawContext->patchLevelTextureBuffer) { + if (osdDrawContext->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_BUFFER, - osdDrawContext->patchLevelTextureBuffer); + osdDrawContext->GetPatchParamTextureBuffer()); } - if (osdDrawContext->fvarDataTextureBuffer) { - glActiveTexture( GL_TEXTURE4 ); - glBindTexture( GL_TEXTURE_BUFFER, - osdDrawContext->fvarDataTextureBuffer ); + if (osdDrawContext->GetFvarDataTextureBuffer()) { + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_BUFFER, + osdDrawContext->GetFvarDataTextureBuffer() ); } glActiveTexture(GL_TEXTURE0); diff --git a/examples/mayaViewer/OpenSubdivShader.h b/examples/mayaViewer/OpenSubdivShader.h index 5f9d4f17..2c63840a 100644 --- a/examples/mayaViewer/OpenSubdivShader.h +++ b/examples/mayaViewer/OpenSubdivShader.h @@ -123,7 +123,7 @@ private: GLuint bindTexture(const MString& filename, int textureUnit); GLuint bindProgram(const MHWRender::MDrawContext & mDrawContext, OpenSubdiv::OsdGLDrawContext *osdDrawContext, - const OpenSubdiv::OsdPatchArray & patch); + const OpenSubdiv::OsdDrawContext::PatchArray & patch); // OSD attributes static MObject aLevel; diff --git a/examples/mayaViewer/shader.glsl b/examples/mayaViewer/shader.glsl index 300bfbb1..7bf1e46e 100644 --- a/examples/mayaViewer/shader.glsl +++ b/examples/mayaViewer/shader.glsl @@ -170,7 +170,8 @@ void emitAdaptive(int index, vec3 normal, vec2 uvs[4]) #endif // Bi-linear interpolation within the patch - vec2 st = input[index].v.patchCoord.st; + output.v.patchCoord = input[index].v.patchCoord; + vec2 st = input[index].v.tessCoord; output.v.patchCoord.st = vec2( mix( mix(uvs[0].x, uvs[1].x, st.s ), mix(uvs[3].x, uvs[2].x, st.s ), st.t), mix( mix(uvs[0].y, uvs[1].y, st.s ), mix(uvs[3].y, uvs[2].y, st.s ), st.t) ); diff --git a/opensubdiv/osd/glDrawContext.h b/opensubdiv/osd/glDrawContext.h index f0e9c263..30139952 100644 --- a/opensubdiv/osd/glDrawContext.h +++ b/opensubdiv/osd/glDrawContext.h @@ -157,6 +157,11 @@ public: return _quadOffsetsTextureBuffer; } + /// Returns the GL texture buffer containing fvar data + GLuint GetFvarDataTextureBuffer() const { + return _fvarDataTextureBuffer; + } + protected: GLuint _patchIndexBuffer; diff --git a/opensubdiv/osd/glslPatchCommon.glsl b/opensubdiv/osd/glslPatchCommon.glsl index 68c2284e..5fae99f2 100644 --- a/opensubdiv/osd/glslPatchCommon.glsl +++ b/opensubdiv/osd/glslPatchCommon.glsl @@ -82,6 +82,7 @@ struct OutputVertex { vec3 normal; vec3 tangent; centroid vec4 patchCoord; // u, v, level, faceID + centroid vec2 tessCoord; // tesscoord.st noperspective vec4 edgeDistance; #if OSD_NUM_VARYINGS > 0 float varyings[OSD_NUM_VARYINGS]; @@ -191,6 +192,7 @@ int GetPatchLevel() ivec2 p = input[0].v.ptexInfo.xy; \ int lv = input[0].v.ptexInfo.z; \ int rot = input[0].v.ptexInfo.w; \ + output.v.tessCoord.xy = uv; \ uv.xy = float(rot==0)*uv.xy \ + float(rot==1)*vec2(1.0-uv.y, uv.x) \ + float(rot==2)*vec2(1.0-uv.x, 1.0-uv.y) \