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