mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-10 06:10:07 +00:00
Merge pull request #422 from davidgyu/patch-drawing
Unified adaptive patch drawing
This commit is contained in:
commit
aec1f61fb0
@ -24,57 +24,25 @@
|
|||||||
|
|
||||||
#include "patchColors.h"
|
#include "patchColors.h"
|
||||||
|
|
||||||
static float _colors[5][7][4] = {{{1.0f, 1.0f, 1.0f, 1.0f}, // regular
|
static float _colors[7][4] = {{1.0f, 1.0f, 1.0f, 1.0f}, // regular
|
||||||
{1.0f, 0.5f, 0.5f, 1.0f}, // single crease
|
{1.0f, 0.5f, 0.5f, 1.0f}, // single crease
|
||||||
{0.8f, 0.0f, 0.0f, 1.0f}, // boundary
|
{0.8f, 0.0f, 0.0f, 1.0f}, // boundary
|
||||||
{0.0f, 1.0f, 0.0f, 1.0f}, // corner
|
{0.0f, 1.0f, 0.0f, 1.0f}, // corner
|
||||||
{1.0f, 1.0f, 0.0f, 1.0f}, // gregory
|
{1.0f, 1.0f, 0.0f, 1.0f}, // gregory
|
||||||
{1.0f, 0.5f, 0.0f, 1.0f}, // gregory boundary
|
{1.0f, 0.5f, 0.0f, 1.0f}, // gregory boundary
|
||||||
{1.0f, 0.7f, 0.3f, 1.0f}}, // gregory basis
|
{1.0f, 0.7f, 0.3f, 1.0f}}; // gregory basis
|
||||||
|
|
||||||
{{0.0f, 1.0f, 1.0f, 1.0f}, // regular pattern 0
|
|
||||||
{0.0f, 0.5f, 1.0f, 1.0f}, // regular pattern 1
|
|
||||||
{0.0f, 0.5f, 0.5f, 1.0f}, // regular pattern 2
|
|
||||||
{0.5f, 0.0f, 1.0f, 1.0f}, // regular pattern 3
|
|
||||||
{1.0f, 0.5f, 1.0f, 1.0f}}, // regular pattern 4
|
|
||||||
|
|
||||||
{{1.0f, 0.70f, 0.6f, 1.0f}, // single crease pattern 0
|
|
||||||
{1.0f, 0.65f, 0.6f, 1.0f}, // single crease pattern 1
|
|
||||||
{1.0f, 0.60f, 0.6f, 1.0f}, // single crease pattern 2
|
|
||||||
{1.0f, 0.55f, 0.6f, 1.0f}, // single crease pattern 3
|
|
||||||
{1.0f, 0.50f, 0.6f, 1.0f}}, // single crease pattern 4
|
|
||||||
|
|
||||||
{{0.0f, 0.0f, 0.75f, 1.0f}, // boundary pattern 0
|
|
||||||
{0.0f, 0.2f, 0.75f, 1.0f}, // boundary pattern 1
|
|
||||||
{0.0f, 0.4f, 0.75f, 1.0f}, // boundary pattern 2
|
|
||||||
{0.0f, 0.6f, 0.75f, 1.0f}, // boundary pattern 3
|
|
||||||
{0.0f, 0.8f, 0.75f, 1.0f}}, // boundary pattern 4
|
|
||||||
|
|
||||||
{{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 0
|
|
||||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 1
|
|
||||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 2
|
|
||||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 3
|
|
||||||
{0.25f, 0.25f, 0.25f, 1.0f}}}; // corner pattern 4
|
|
||||||
|
|
||||||
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
|
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
|
||||||
|
|
||||||
float const *
|
float const *
|
||||||
getAdaptivePatchColor(Descriptor const & desc) {
|
getAdaptivePatchColor(Descriptor const & desc) {
|
||||||
|
|
||||||
if (desc.GetPattern()==Descriptor::NON_TRANSITION) {
|
return _colors[(int)(desc.GetType()-Descriptor::REGULAR)];
|
||||||
return _colors[0][(int)(desc.GetType()-Descriptor::REGULAR)];
|
|
||||||
} else {
|
|
||||||
return _colors[(int)(desc.GetType()-Descriptor::REGULAR)+1][(int)desc.GetPattern()-1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float const *
|
float const *
|
||||||
getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc) {
|
getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc) {
|
||||||
|
|
||||||
if (desc.GetPattern()==Descriptor::NON_TRANSITION) {
|
return _colors[(int)(desc.GetType()-Descriptor::REGULAR)];
|
||||||
return _colors[0][(int)(desc.GetType()-Descriptor::REGULAR)];
|
|
||||||
} else {
|
|
||||||
return _colors[(int)(desc.GetType()-Descriptor::REGULAR)+1][(int)desc.GetPattern()-1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1755,7 +1755,7 @@ drawCageEdges() {
|
|||||||
typedef OpenSubdiv::Far::PatchDescriptor FDesc;
|
typedef OpenSubdiv::Far::PatchDescriptor FDesc;
|
||||||
|
|
||||||
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc(
|
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc(
|
||||||
FDesc(FDesc::LINES, FDesc::NON_TRANSITION, 0), 0, 0, 0);
|
FDesc(FDesc::LINES), 0, 0);
|
||||||
EffectDrawRegistry::ConfigType *config = getInstance(effect, desc);
|
EffectDrawRegistry::ConfigType *config = getInstance(effect, desc);
|
||||||
glUseProgram(config->program);
|
glUseProgram(config->program);
|
||||||
|
|
||||||
|
@ -423,7 +423,85 @@ layout(std140) uniform Lighting {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if defined COLOR_PATCHTYPE
|
#if defined COLOR_PATCHTYPE
|
||||||
|
|
||||||
uniform vec4 overrideColor;
|
uniform vec4 overrideColor;
|
||||||
|
|
||||||
|
vec4
|
||||||
|
GetOverrideColor(int patchParam)
|
||||||
|
{
|
||||||
|
const vec4 patchColors[7*6] = vec4[7*6](
|
||||||
|
vec4(1.0f, 1.0f, 1.0f, 1.0f), // regular
|
||||||
|
vec4(0.0f, 1.0f, 1.0f, 1.0f), // regular pattern 0
|
||||||
|
vec4(0.0f, 0.5f, 1.0f, 1.0f), // regular pattern 1
|
||||||
|
vec4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||||
|
vec4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
||||||
|
vec4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
||||||
|
|
||||||
|
vec4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
||||||
|
vec4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
||||||
|
vec4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
||||||
|
vec4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
||||||
|
vec4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
||||||
|
vec4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
||||||
|
|
||||||
|
vec4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
||||||
|
vec4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
||||||
|
vec4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
||||||
|
vec4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
||||||
|
vec4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
||||||
|
vec4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
||||||
|
|
||||||
|
vec4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
||||||
|
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f) // gregory basis
|
||||||
|
);
|
||||||
|
|
||||||
|
int patchType = 0;
|
||||||
|
#if defined OSD_PATCH_SINGLE_CREASE
|
||||||
|
patchType = 1;
|
||||||
|
#elif defined OSD_PATCH_GREGORY
|
||||||
|
patchType = 4;
|
||||||
|
#elif defined OSD_PATCH_GREGORY_BOUNDARY
|
||||||
|
patchType = 5;
|
||||||
|
#elif defined OSD_PATCH_GREGORY_BASIS
|
||||||
|
patchType = 6;
|
||||||
|
#endif
|
||||||
|
int edgeCount = bitCount((patchParam >> 4) & 0xf);
|
||||||
|
if (edgeCount == 1) {
|
||||||
|
patchType = 2; // BOUNDARY
|
||||||
|
}
|
||||||
|
if (edgeCount == 2) {
|
||||||
|
patchType = 3; // CORNER
|
||||||
|
}
|
||||||
|
int pattern = bitCount((patchParam >> 8) & 0xf);
|
||||||
|
int offset = 7*patchType + pattern;
|
||||||
|
return patchColors[offset];
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NORMAL_HW_SCREENSPACE) || defined(NORMAL_SCREENSPACE)
|
#if defined(NORMAL_HW_SCREENSPACE) || defined(NORMAL_SCREENSPACE)
|
||||||
@ -597,7 +675,7 @@ main()
|
|||||||
textureImage_Data,
|
textureImage_Data,
|
||||||
textureImage_Packing);
|
textureImage_Packing);
|
||||||
#elif defined COLOR_PATCHTYPE
|
#elif defined COLOR_PATCHTYPE
|
||||||
vec4 texColor = edgeColor(lighting(overrideColor, inpt.v.position.xyz, normal, 1, 0));
|
vec4 texColor = edgeColor(lighting(GetOverrideColor(GetPatchParam()), inpt.v.position.xyz, normal, 1, 0));
|
||||||
outColor = texColor;
|
outColor = texColor;
|
||||||
return;
|
return;
|
||||||
#elif defined COLOR_PATCHCOORD
|
#elif defined COLOR_PATCHCOORD
|
||||||
|
@ -1158,7 +1158,7 @@ display() {
|
|||||||
g_mesh->GetDrawContext()->GetPatchArrays();
|
g_mesh->GetDrawContext()->GetPatchArrays();
|
||||||
|
|
||||||
// patch drawing
|
// patch drawing
|
||||||
int patchCount[13][6][4]; // [Type][Pattern][Rotation] (see far/patchTables.h)
|
int patchCount[13]; // [Type] (see far/patchTables.h)
|
||||||
int numTotalPatches = 0;
|
int numTotalPatches = 0;
|
||||||
int numDrawCalls = 0;
|
int numDrawCalls = 0;
|
||||||
memset(patchCount, 0, sizeof(patchCount));
|
memset(patchCount, 0, sizeof(patchCount));
|
||||||
@ -1174,13 +1174,8 @@ display() {
|
|||||||
|
|
||||||
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||||
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
|
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
|
||||||
int patchPattern = desc.GetPattern();
|
|
||||||
int patchRotation = desc.GetRotation();
|
|
||||||
int subPatch = desc.GetSubPatch();
|
|
||||||
|
|
||||||
if (subPatch == 0) {
|
patchCount[patchType] += patch.GetNumPatches();
|
||||||
patchCount[patchType][patchPattern][patchRotation] += patch.GetNumPatches();
|
|
||||||
}
|
|
||||||
numTotalPatches += patch.GetNumPatches();
|
numTotalPatches += patch.GetNumPatches();
|
||||||
|
|
||||||
GLenum primType;
|
GLenum primType;
|
||||||
@ -1192,6 +1187,9 @@ display() {
|
|||||||
case OpenSubdiv::Far::PatchDescriptor::TRIANGLES:
|
case OpenSubdiv::Far::PatchDescriptor::TRIANGLES:
|
||||||
primType = GL_TRIANGLES;
|
primType = GL_TRIANGLES;
|
||||||
break;
|
break;
|
||||||
|
case OpenSubdiv::Far::PatchDescriptor::SINGLE_CREASE: // XXXdyu-patch-drawing
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||||
primType = GL_PATCHES;
|
primType = GL_PATCHES;
|
||||||
@ -1288,48 +1286,21 @@ display() {
|
|||||||
int x = -280;
|
int x = -280;
|
||||||
int y = -480;
|
int y = -480;
|
||||||
g_hud.DrawString(x, y, "NonPatch : %d",
|
g_hud.DrawString(x, y, "NonPatch : %d",
|
||||||
patchCount[Descriptor::QUADS][0][0]); y += 20;
|
patchCount[Descriptor::QUADS]); y += 20;
|
||||||
g_hud.DrawString(x, y, "Regular : %d",
|
g_hud.DrawString(x, y, "Regular : %d",
|
||||||
patchCount[Descriptor::REGULAR][0][0]); y+= 20;
|
patchCount[Descriptor::REGULAR]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Boundary : %d",
|
g_hud.DrawString(x, y, "Boundary : %d",
|
||||||
patchCount[Descriptor::BOUNDARY][0][0]); y+= 20;
|
patchCount[Descriptor::BOUNDARY]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Corner : %d",
|
g_hud.DrawString(x, y, "Corner : %d",
|
||||||
patchCount[Descriptor::CORNER][0][0]); y+= 20;
|
patchCount[Descriptor::CORNER]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Single Crease : %d",
|
g_hud.DrawString(x, y, "Single Crease : %d",
|
||||||
patchCount[Descriptor::SINGLE_CREASE][0][0]); y+= 20;
|
patchCount[Descriptor::SINGLE_CREASE]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Gregory : %d",
|
g_hud.DrawString(x, y, "Gregory : %d",
|
||||||
patchCount[Descriptor::GREGORY][0][0]); y+= 20;
|
patchCount[Descriptor::GREGORY]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Boundary Gregory : %d",
|
g_hud.DrawString(x, y, "Boundary Gregory : %d",
|
||||||
patchCount[Descriptor::GREGORY_BOUNDARY][0][0]); y+= 20;
|
patchCount[Descriptor::GREGORY_BOUNDARY]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Gregory Basis : %d",
|
g_hud.DrawString(x, y, "Gregory Basis : %d",
|
||||||
patchCount[Descriptor::GREGORY_BASIS][0][0]); y+= 20;
|
patchCount[Descriptor::GREGORY_BASIS]); y+= 20;
|
||||||
g_hud.DrawString(x, y, "Trans. Regular : %d %d %d %d %d",
|
|
||||||
patchCount[Descriptor::REGULAR][Descriptor::PATTERN0][0],
|
|
||||||
patchCount[Descriptor::REGULAR][Descriptor::PATTERN1][0],
|
|
||||||
patchCount[Descriptor::REGULAR][Descriptor::PATTERN2][0],
|
|
||||||
patchCount[Descriptor::REGULAR][Descriptor::PATTERN3][0],
|
|
||||||
patchCount[Descriptor::REGULAR][Descriptor::PATTERN4][0]); y+= 20;
|
|
||||||
for (int i=0; i < 5; i++) {
|
|
||||||
g_hud.DrawString(x, y, "Trans. Boundary%d : %d %d %d %d", i,
|
|
||||||
patchCount[Descriptor::BOUNDARY][i+1][0],
|
|
||||||
patchCount[Descriptor::BOUNDARY][i+1][1],
|
|
||||||
patchCount[Descriptor::BOUNDARY][i+1][2],
|
|
||||||
patchCount[Descriptor::BOUNDARY][i+1][3]); y+= 20;
|
|
||||||
}
|
|
||||||
for (int i=0; i < 5; i++) {
|
|
||||||
g_hud.DrawString(x, y, "Trans. Corner%d : %d %d %d %d", i,
|
|
||||||
patchCount[Descriptor::CORNER][i+1][0],
|
|
||||||
patchCount[Descriptor::CORNER][i+1][1],
|
|
||||||
patchCount[Descriptor::CORNER][i+1][2],
|
|
||||||
patchCount[Descriptor::CORNER][i+1][3]); y+= 20;
|
|
||||||
}
|
|
||||||
for (int i=0; i < 5; i++) {
|
|
||||||
g_hud.DrawString(x, y, "Trans. Single Crease%d : %d %d %d %d", i,
|
|
||||||
patchCount[Descriptor::SINGLE_CREASE][i+1][0],
|
|
||||||
patchCount[Descriptor::SINGLE_CREASE][i+1][1],
|
|
||||||
patchCount[Descriptor::SINGLE_CREASE][i+1][2],
|
|
||||||
patchCount[Descriptor::SINGLE_CREASE][i+1][3]); y+= 20;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int y = -220;
|
int y = -220;
|
||||||
|
@ -374,6 +374,84 @@ edgeColor(vec4 Cfill, vec4 edgeDistance)
|
|||||||
return Cfill;
|
return Cfill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4
|
||||||
|
getAdaptivePatchColor(int patchParam)
|
||||||
|
{
|
||||||
|
const vec4 patchColors[7*6] = vec4[7*6](
|
||||||
|
vec4(1.0f, 1.0f, 1.0f, 1.0f), // regular
|
||||||
|
vec4(0.0f, 1.0f, 1.0f, 1.0f), // regular pattern 0
|
||||||
|
vec4(0.0f, 0.5f, 1.0f, 1.0f), // regular pattern 1
|
||||||
|
vec4(0.0f, 0.5f, 0.5f, 1.0f), // regular pattern 2
|
||||||
|
vec4(0.5f, 0.0f, 1.0f, 1.0f), // regular pattern 3
|
||||||
|
vec4(1.0f, 0.5f, 1.0f, 1.0f), // regular pattern 4
|
||||||
|
|
||||||
|
vec4(1.0f, 0.5f, 0.5f, 1.0f), // single crease
|
||||||
|
vec4(1.0f, 0.70f, 0.6f, 1.0f), // single crease pattern 0
|
||||||
|
vec4(1.0f, 0.65f, 0.6f, 1.0f), // single crease pattern 1
|
||||||
|
vec4(1.0f, 0.60f, 0.6f, 1.0f), // single crease pattern 2
|
||||||
|
vec4(1.0f, 0.55f, 0.6f, 1.0f), // single crease pattern 3
|
||||||
|
vec4(1.0f, 0.50f, 0.6f, 1.0f), // single crease pattern 4
|
||||||
|
|
||||||
|
vec4(0.8f, 0.0f, 0.0f, 1.0f), // boundary
|
||||||
|
vec4(0.0f, 0.0f, 0.75f, 1.0f), // boundary pattern 0
|
||||||
|
vec4(0.0f, 0.2f, 0.75f, 1.0f), // boundary pattern 1
|
||||||
|
vec4(0.0f, 0.4f, 0.75f, 1.0f), // boundary pattern 2
|
||||||
|
vec4(0.0f, 0.6f, 0.75f, 1.0f), // boundary pattern 3
|
||||||
|
vec4(0.0f, 0.8f, 0.75f, 1.0f), // boundary pattern 4
|
||||||
|
|
||||||
|
vec4(0.0f, 1.0f, 0.0f, 1.0f), // corner
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 0
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 1
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 2
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 3
|
||||||
|
vec4(0.25f, 0.25f, 0.25f, 1.0f), // corner pattern 4
|
||||||
|
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
vec4(1.0f, 1.0f, 0.0f, 1.0f), // gregory
|
||||||
|
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
vec4(1.0f, 0.5f, 0.0f, 1.0f), // gregory boundary
|
||||||
|
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f), // gregory basis
|
||||||
|
vec4(1.0f, 0.7f, 0.3f, 1.0f) // gregory basis
|
||||||
|
);
|
||||||
|
|
||||||
|
int patchType = 0;
|
||||||
|
#if defined OSD_PATCH_SINGLE_CREASE
|
||||||
|
patchType = 1;
|
||||||
|
#elif defined OSD_PATCH_GREGORY
|
||||||
|
patchType = 4;
|
||||||
|
#elif defined OSD_PATCH_GREGORY_BOUNDARY
|
||||||
|
patchType = 5;
|
||||||
|
#elif defined OSD_PATCH_GREGORY_BASIS
|
||||||
|
patchType = 6;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int edgeCount = bitCount((patchParam >> 4) & 0xf);
|
||||||
|
if (edgeCount == 1) {
|
||||||
|
patchType = 2; // BOUNDARY
|
||||||
|
}
|
||||||
|
if (edgeCount == 2) {
|
||||||
|
patchType = 3; // CORNER
|
||||||
|
}
|
||||||
|
|
||||||
|
int pattern = bitCount((patchParam >> 8) & 0xf);
|
||||||
|
|
||||||
|
return patchColors[7*patchType + pattern];
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
||||||
void
|
void
|
||||||
main()
|
main()
|
||||||
@ -387,7 +465,8 @@ main()
|
|||||||
vec4 color = vec4(inpt.color.rg,
|
vec4 color = vec4(inpt.color.rg,
|
||||||
int(floor(20*inpt.color.r)+floor(20*inpt.color.g))&1, 1);
|
int(floor(20*inpt.color.r)+floor(20*inpt.color.g))&1, 1);
|
||||||
#else
|
#else
|
||||||
vec4 color = diffuseColor;
|
//vec4 color = diffuseColor;
|
||||||
|
vec4 color = getAdaptivePatchColor(GetPatchParam());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec4 Cf = lighting(color, inpt.v.position.xyz, N);
|
vec4 Cf = lighting(color, inpt.v.position.xyz, N);
|
||||||
|
@ -43,94 +43,19 @@ PatchDescriptor::GetAdaptivePatchDescriptors(Sdc::SchemeType type) {
|
|||||||
|
|
||||||
static PatchDescriptor _loopDescriptors[] = {
|
static PatchDescriptor _loopDescriptors[] = {
|
||||||
// XXXX work in progress !
|
// XXXX work in progress !
|
||||||
PatchDescriptor(LOOP, NON_TRANSITION, 0)
|
PatchDescriptor(LOOP),
|
||||||
};
|
};
|
||||||
|
|
||||||
static PatchDescriptor _catmarkDescriptors[] = {
|
static PatchDescriptor _catmarkDescriptors[] = {
|
||||||
|
|
||||||
// non-transition patches : 7
|
// XXXdyu-patch-drawing
|
||||||
PatchDescriptor(REGULAR, NON_TRANSITION, 0),
|
PatchDescriptor(REGULAR),
|
||||||
PatchDescriptor(SINGLE_CREASE, NON_TRANSITION, 0),
|
PatchDescriptor(SINGLE_CREASE),
|
||||||
PatchDescriptor(BOUNDARY, NON_TRANSITION, 0),
|
PatchDescriptor(BOUNDARY),
|
||||||
PatchDescriptor(CORNER, NON_TRANSITION, 0),
|
PatchDescriptor(CORNER),
|
||||||
PatchDescriptor(GREGORY, NON_TRANSITION, 0),
|
PatchDescriptor(GREGORY),
|
||||||
PatchDescriptor(GREGORY_BOUNDARY, NON_TRANSITION, 0),
|
PatchDescriptor(GREGORY_BOUNDARY),
|
||||||
PatchDescriptor(GREGORY_BASIS, NON_TRANSITION, 0),
|
PatchDescriptor(GREGORY_BASIS),
|
||||||
|
|
||||||
// transition pattern 0
|
|
||||||
PatchDescriptor(REGULAR, PATTERN0, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN0, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN0, 1),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN0, 2),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN0, 3),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN0, 0),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN0, 1),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN0, 2),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN0, 3),
|
|
||||||
PatchDescriptor(CORNER, PATTERN0, 0),
|
|
||||||
PatchDescriptor(CORNER, PATTERN0, 1),
|
|
||||||
PatchDescriptor(CORNER, PATTERN0, 2),
|
|
||||||
PatchDescriptor(CORNER, PATTERN0, 3),
|
|
||||||
|
|
||||||
// transition pattern 1
|
|
||||||
PatchDescriptor(REGULAR, PATTERN1, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN1, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN1, 1),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN1, 2),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN1, 3),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN1, 0),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN1, 1),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN1, 2),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN1, 3),
|
|
||||||
PatchDescriptor(CORNER, PATTERN1, 0),
|
|
||||||
PatchDescriptor(CORNER, PATTERN1, 1),
|
|
||||||
PatchDescriptor(CORNER, PATTERN1, 2),
|
|
||||||
PatchDescriptor(CORNER, PATTERN1, 3),
|
|
||||||
|
|
||||||
// transition pattern 2
|
|
||||||
PatchDescriptor(REGULAR, PATTERN2, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN2, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN2, 1),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN2, 2),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN2, 3),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN2, 0),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN2, 1),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN2, 2),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN2, 3),
|
|
||||||
PatchDescriptor(CORNER, PATTERN2, 0),
|
|
||||||
PatchDescriptor(CORNER, PATTERN2, 1),
|
|
||||||
PatchDescriptor(CORNER, PATTERN2, 2),
|
|
||||||
PatchDescriptor(CORNER, PATTERN2, 3),
|
|
||||||
|
|
||||||
// transition pattern 3
|
|
||||||
PatchDescriptor(REGULAR, PATTERN3, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN3, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN3, 1),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN3, 2),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN3, 3),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN3, 0),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN3, 1),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN3, 2),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN3, 3),
|
|
||||||
PatchDescriptor(CORNER, PATTERN3, 0),
|
|
||||||
PatchDescriptor(CORNER, PATTERN3, 1),
|
|
||||||
PatchDescriptor(CORNER, PATTERN3, 2),
|
|
||||||
PatchDescriptor(CORNER, PATTERN3, 3),
|
|
||||||
|
|
||||||
// transition pattern 4
|
|
||||||
PatchDescriptor(REGULAR, PATTERN4, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN4, 0),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN4, 1),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN4, 2),
|
|
||||||
PatchDescriptor(SINGLE_CREASE, PATTERN4, 3),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN4, 0),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN4, 1),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN4, 2),
|
|
||||||
PatchDescriptor(BOUNDARY, PATTERN4, 3),
|
|
||||||
PatchDescriptor(CORNER, PATTERN4, 0),
|
|
||||||
PatchDescriptor(CORNER, PATTERN4, 1),
|
|
||||||
PatchDescriptor(CORNER, PATTERN4, 2),
|
|
||||||
PatchDescriptor(CORNER, PATTERN4, 3),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -155,8 +80,8 @@ PatchDescriptor::print() const {
|
|||||||
"SINGLE_CREASE", "BOUNDARY", "CORNER", "GREGORY",
|
"SINGLE_CREASE", "BOUNDARY", "CORNER", "GREGORY",
|
||||||
"GREGORY_BOUNDARY", "GREGORY_BASIS" };
|
"GREGORY_BOUNDARY", "GREGORY_BASIS" };
|
||||||
|
|
||||||
printf(" type %s trans %d rot %d\n",
|
printf(" type %s\n",
|
||||||
types[_type], _pattern, _rotation);
|
types[_type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,11 +51,9 @@ namespace Far {
|
|||||||
///
|
///
|
||||||
/// Bitfield layout :
|
/// Bitfield layout :
|
||||||
///
|
///
|
||||||
/// Field | Bits | Content
|
/// Field | Bits | Content
|
||||||
/// -----------|:----:|------------------------------------------------------
|
/// ------------|:----:|------------------------------------------------------
|
||||||
/// _type | 4 | patch type
|
/// _type | 4 | patch type
|
||||||
/// _pattern | 3 | patch transition pattern
|
|
||||||
/// _rotation | 2 | patch rotation
|
|
||||||
///
|
///
|
||||||
class PatchDescriptor {
|
class PatchDescriptor {
|
||||||
|
|
||||||
@ -81,44 +79,25 @@ public:
|
|||||||
GREGORY_BASIS
|
GREGORY_BASIS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TransitionPattern {
|
|
||||||
NON_TRANSITION = 0,
|
|
||||||
PATTERN0,
|
|
||||||
PATTERN1,
|
|
||||||
PATTERN2,
|
|
||||||
PATTERN3,
|
|
||||||
PATTERN4
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// \brief Default constructor.
|
/// \brief Default constructor.
|
||||||
PatchDescriptor() :
|
PatchDescriptor() :
|
||||||
_type(NON_PATCH), _pattern(NON_TRANSITION), _rotation(0) {}
|
_type(NON_PATCH) { }
|
||||||
|
|
||||||
/// \brief Constructor
|
/// \brief Constructor
|
||||||
PatchDescriptor(int type, int pattern, unsigned char rotation) :
|
PatchDescriptor(int type) :
|
||||||
_type(type), _pattern(pattern), _rotation(rotation) { }
|
_type(type) { }
|
||||||
|
|
||||||
/// \brief Copy Constructor
|
/// \brief Copy Constructor
|
||||||
PatchDescriptor( PatchDescriptor const & d ) :
|
PatchDescriptor( PatchDescriptor const & d ) :
|
||||||
_type(d.GetType()), _pattern(d.GetPattern()), _rotation(d.GetRotation()) { }
|
_type(d.GetType()) { }
|
||||||
|
|
||||||
/// \brief Returns the type of the patch
|
/// \brief Returns the type of the patch
|
||||||
Type GetType() const {
|
Type GetType() const {
|
||||||
return (Type)_type;
|
return (Type)_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns the transition pattern of the patch if any (5 types)
|
|
||||||
TransitionPattern GetPattern() const {
|
|
||||||
return (TransitionPattern)_pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the rotation of the patch (4 rotations)
|
|
||||||
unsigned char GetRotation() const {
|
|
||||||
return (unsigned char)_rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns true if the type is an adaptive patch
|
/// \brief Returns true if the type is an adaptive patch
|
||||||
static inline bool IsAdaptive(Type type) {
|
static inline bool IsAdaptive(Type type) {
|
||||||
return (type>=LOOP and type<=GREGORY_BASIS);
|
return (type>=LOOP and type<=GREGORY_BASIS);
|
||||||
@ -151,10 +130,10 @@ public:
|
|||||||
static short GetRegularPatchSize() { return 16; }
|
static short GetRegularPatchSize() { return 16; }
|
||||||
|
|
||||||
/// \brief Number of control vertices of Boundary Patches in table.
|
/// \brief Number of control vertices of Boundary Patches in table.
|
||||||
static short GetBoundaryPatchSize() { return 12; }
|
static short GetBoundaryPatchSize() { return 16; }
|
||||||
|
|
||||||
/// \brief Number of control vertices of Boundary Patches in table.
|
/// \brief Number of control vertices of Boundary Patches in table.
|
||||||
static short GetCornerPatchSize() { return 9; }
|
static short GetCornerPatchSize() { return 16; }
|
||||||
|
|
||||||
/// \brief Number of control vertices of Gregory (and Gregory Boundary) Patches in table.
|
/// \brief Number of control vertices of Gregory (and Gregory Boundary) Patches in table.
|
||||||
static short GetGregoryPatchSize() { return 4; }
|
static short GetGregoryPatchSize() { return 4; }
|
||||||
@ -180,8 +159,6 @@ private:
|
|||||||
friend class PatchTablesFactory;
|
friend class PatchTablesFactory;
|
||||||
|
|
||||||
unsigned int _type:4;
|
unsigned int _type:4;
|
||||||
unsigned int _pattern:3;
|
|
||||||
unsigned int _rotation:2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Vtr::ConstArray<PatchDescriptor> ConstPatchDescriptorArray;
|
typedef Vtr::ConstArray<PatchDescriptor> ConstPatchDescriptorArray;
|
||||||
@ -227,17 +204,13 @@ PatchDescriptor::GetNumFVarControlVertices( Type type ) {
|
|||||||
// Allows ordering of patches by type
|
// Allows ordering of patches by type
|
||||||
inline bool
|
inline bool
|
||||||
PatchDescriptor::operator < ( PatchDescriptor const other ) const {
|
PatchDescriptor::operator < ( PatchDescriptor const other ) const {
|
||||||
return _pattern < other._pattern or ((_pattern == other._pattern) and
|
return (_type < other._type);
|
||||||
(_type < other._type or ((_type == other._type) and
|
|
||||||
(_rotation < other._rotation))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if the descriptors are identical
|
// True if the descriptors are identical
|
||||||
inline bool
|
inline bool
|
||||||
PatchDescriptor::operator == ( PatchDescriptor const other ) const {
|
PatchDescriptor::operator == ( PatchDescriptor const other ) const {
|
||||||
return _pattern == other._pattern and
|
return _type == other._type;
|
||||||
_type == other._type and
|
|
||||||
_rotation == other._rotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ namespace Far {
|
|||||||
///
|
///
|
||||||
/// Field | Bits | Content
|
/// Field | Bits | Content
|
||||||
/// -----------|:----:|------------------------------------------------------
|
/// -----------|:----:|------------------------------------------------------
|
||||||
/// level | 4 | the subdivision level of the patch
|
/// level | 3 | the subdivision level of the patch
|
||||||
/// nonquad | 1 | whether the patch is the child of a non-quad face
|
/// nonquad | 1 | whether the patch is the child of a non-quad face
|
||||||
/// rotation | 2 | patch rotations necessary to match CCW face-winding
|
/// boundary | 4 | boundary edge mask encoding
|
||||||
|
/// transition | 4 | transition edge mask encoding
|
||||||
/// v | 10 | log2 value of u parameter at first patch corner
|
/// v | 10 | log2 value of u parameter at first patch corner
|
||||||
/// u | 10 | log2 value of v parameter at first patch corner
|
/// u | 10 | log2 value of v parameter at first patch corner
|
||||||
/// reserved1 | 5 | padding
|
|
||||||
///
|
///
|
||||||
/// Note : the bitfield is not expanded in the struct due to differences in how
|
/// Note : the bitfield is not expanded in the struct due to differences in how
|
||||||
/// GPU & CPU compilers pack bit-fields and endian-ness.
|
/// GPU & CPU compilers pack bit-fields and endian-ness.
|
||||||
@ -73,28 +73,35 @@ struct PatchParam {
|
|||||||
/// @param depth subdivision level of the patch
|
/// @param depth subdivision level of the patch
|
||||||
/// @param nonquad true if the root face is not a quad
|
/// @param nonquad true if the root face is not a quad
|
||||||
///
|
///
|
||||||
void Set( short u, short v, unsigned char rots, unsigned char depth, bool nonquad );
|
void Set( short u, short v, unsigned char depth, bool nonquad,
|
||||||
|
unsigned short boundary, unsigned short transition );
|
||||||
|
|
||||||
/// \brief Returns the log2 value of the u parameter at the top left corner of
|
/// \brief Returns the log2 value of the u parameter at the top left corner of
|
||||||
/// the patch
|
/// the patch
|
||||||
unsigned short GetU() const { return (unsigned short)((field >> 17) & 0x3ff); }
|
unsigned short GetU() const { return (unsigned short)((field >> 22) & 0x3ff); }
|
||||||
|
|
||||||
/// \brief Returns the log2 value of the v parameter at the top left corner of
|
/// \brief Returns the log2 value of the v parameter at the top left corner of
|
||||||
/// the patch
|
/// the patch
|
||||||
unsigned short GetV() const { return (unsigned short)((field >> 7) & 0x3ff); }
|
unsigned short GetV() const { return (unsigned short)((field >> 12) & 0x3ff); }
|
||||||
|
|
||||||
/// \brief Returns the rotation of the patch (the number of CCW parameter winding)
|
/// \brief Returns the transition edge encoding for the patch.
|
||||||
unsigned char GetRotation() const { return (unsigned char)((field >> 5) & 0x3); }
|
unsigned short GetTransition() const { return (unsigned short)((field >> 8) & 0xf); }
|
||||||
|
|
||||||
|
/// \brief Returns the boundary edge encoding for the patch.
|
||||||
|
unsigned short GetBoundary() const { return (unsigned short)((field >> 4) & 0xf); }
|
||||||
|
|
||||||
|
/// \brief Deprecated XXXdyu-patch-drawing (patches rotated when gathered from refiner)
|
||||||
|
unsigned char GetRotation() const { return 0; }
|
||||||
|
|
||||||
/// \brief True if the parent coarse face is a non-quad
|
/// \brief True if the parent coarse face is a non-quad
|
||||||
bool NonQuadRoot() const { return (field >> 4) & 0x1; }
|
bool NonQuadRoot() const { return (field >> 3) & 0x1; }
|
||||||
|
|
||||||
/// \brief Returns the fratcion of normalized parametric space covered by the
|
/// \brief Returns the fratcion of normalized parametric space covered by the
|
||||||
/// sub-patch.
|
/// sub-patch.
|
||||||
float GetParamFraction() const;
|
float GetParamFraction() const;
|
||||||
|
|
||||||
/// \brief Returns the level of subdivision of the patch
|
/// \brief Returns the level of subdivision of the patch
|
||||||
unsigned char GetDepth() const { return (unsigned char)(field & 0xf); }
|
unsigned char GetDepth() const { return (unsigned char)(field & 0x7); }
|
||||||
|
|
||||||
/// The (u,v) pair is normalized to this sub-parametric space.
|
/// The (u,v) pair is normalized to this sub-parametric space.
|
||||||
///
|
///
|
||||||
@ -103,14 +110,6 @@ struct PatchParam {
|
|||||||
///
|
///
|
||||||
void Normalize( float & u, float & v ) const;
|
void Normalize( float & u, float & v ) const;
|
||||||
|
|
||||||
/// \brief Rotate (u,v) pair to compensate for transition pattern and boundary
|
|
||||||
/// orientations.
|
|
||||||
///
|
|
||||||
/// @param u u parameter
|
|
||||||
/// @param v v parameter
|
|
||||||
///
|
|
||||||
void Rotate( float & u, float & v ) const;
|
|
||||||
|
|
||||||
/// \brief Resets the values to 0
|
/// \brief Resets the values to 0
|
||||||
void Clear() { field = 0; }
|
void Clear() { field = 0; }
|
||||||
|
|
||||||
@ -127,7 +126,8 @@ struct PatchParam {
|
|||||||
/// @param depth subdivision level of the patch
|
/// @param depth subdivision level of the patch
|
||||||
/// @param nonquad true if the root face is not a quad
|
/// @param nonquad true if the root face is not a quad
|
||||||
///
|
///
|
||||||
void Set( Index faceid, short u, short v, unsigned char rots, unsigned char depth, bool nonquad );
|
void Set( Index faceid, short u, short v, unsigned char depth, bool nonquad ,
|
||||||
|
unsigned short boundary, unsigned short transition );
|
||||||
|
|
||||||
/// \brief Resets everything to 0
|
/// \brief Resets everything to 0
|
||||||
void Clear();
|
void Clear();
|
||||||
@ -139,11 +139,13 @@ typedef Vtr::Array<PatchParam> PatchParamArray;
|
|||||||
typedef Vtr::ConstArray<PatchParam> ConstPatchParamArray;
|
typedef Vtr::ConstArray<PatchParam> ConstPatchParamArray;
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
PatchParam::BitField::Set( short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
PatchParam::BitField::Set( short u, short v, unsigned char depth, bool nonquad,
|
||||||
field = (u << 17) |
|
unsigned short boundary, unsigned short transition ) {
|
||||||
(v << 7) |
|
field = (u << 22) |
|
||||||
(rots << 5) |
|
(v << 12) |
|
||||||
((nonquad ? 1:0) << 4) |
|
(transition << 8) |
|
||||||
|
(boundary << 4) |
|
||||||
|
((nonquad ? 1:0) << 3) |
|
||||||
(nonquad ? depth+1 : depth);
|
(nonquad ? depth+1 : depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,21 +174,10 @@ PatchParam::BitField::Normalize( float & u, float & v ) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
PatchParam::BitField::Rotate( float & u, float & v ) const {
|
PatchParam::Set( Index faceid, short u, short v, unsigned char depth, bool nonquad,
|
||||||
switch( GetRotation() ) {
|
unsigned short boundary, unsigned short transition ) {
|
||||||
case 0 : break;
|
|
||||||
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
|
|
||||||
case 2 : { u=1.0f-u; v=1.0f-v; } break;
|
|
||||||
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
PatchParam::Set( Index faceid, short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
|
||||||
faceIndex = faceid;
|
faceIndex = faceid;
|
||||||
bitField.Set(u,v,rots,depth,nonquad);
|
bitField.Set(u,v,depth,nonquad,boundary,transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -461,7 +461,7 @@ PatchTables::Evaluate(PatchHandle const & handle, float s, float t,
|
|||||||
|
|
||||||
float Q[16], Qd1[16], Qd2[16];
|
float Q[16], Qd1[16], Qd2[16];
|
||||||
|
|
||||||
if (ptype>=PatchDescriptor::REGULAR and ptype<=PatchDescriptor::CORNER) {
|
if (ptype>=PatchDescriptor::REGULAR and ptype<=PatchDescriptor::SINGLE_CREASE) {
|
||||||
|
|
||||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
||||||
|
|
||||||
@ -470,17 +470,13 @@ PatchTables::Evaluate(PatchHandle const & handle, float s, float t,
|
|||||||
switch (ptype) {
|
switch (ptype) {
|
||||||
case PatchDescriptor::REGULAR:
|
case PatchDescriptor::REGULAR:
|
||||||
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
|
// XXXdyu bits InterpolateBoundaryPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
|
// XXXdyu bits InterpolateCornerPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
break;
|
break;
|
||||||
case PatchDescriptor::SINGLE_CREASE:
|
case PatchDescriptor::SINGLE_CREASE:
|
||||||
// TODO: implement InterpolateSingleCreasePatch().
|
// TODO: implement InterpolateSingleCreasePatch().
|
||||||
//InterpolateRegularPatch(cvs, Q, Qd1, Qd2, src, dst);
|
//InterpolateRegularPatch(cvs, Q, Qd1, Qd2, src, dst);
|
||||||
break;
|
break;
|
||||||
case PatchDescriptor::BOUNDARY:
|
|
||||||
InterpolateBoundaryPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
|
||||||
break;
|
|
||||||
case PatchDescriptor::CORNER:
|
|
||||||
InterpolateCornerPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
|
||||||
break;
|
|
||||||
case PatchDescriptor::GREGORY:
|
case PatchDescriptor::GREGORY:
|
||||||
case PatchDescriptor::GREGORY_BOUNDARY:
|
case PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
assert(0);
|
assert(0);
|
||||||
@ -537,14 +533,8 @@ PatchTables::EvaluateFaceVarying(int channel, PatchHandle const & handle,
|
|||||||
case PatchDescriptor::REGULAR:
|
case PatchDescriptor::REGULAR:
|
||||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
||||||
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
break;
|
// XXXdyu bits InterpolateBoundaryPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
case PatchDescriptor::BOUNDARY:
|
// XXXdyu bits InterpolateCornerPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
|
||||||
InterpolateBoundaryPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
|
||||||
break;
|
|
||||||
case PatchDescriptor::CORNER:
|
|
||||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
|
||||||
InterpolateCornerPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -42,50 +42,41 @@ namespace {
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
struct PatchTypes {
|
struct PatchTypes {
|
||||||
|
|
||||||
static const int NUM_TRANSITIONS=6,
|
|
||||||
NUM_ROTATIONS=4;
|
|
||||||
|
|
||||||
TYPE R[NUM_TRANSITIONS], // regular patch
|
TYPE R, // regular patch
|
||||||
S[NUM_TRANSITIONS][NUM_ROTATIONS], // single-crease patch
|
S, // single-crease patch
|
||||||
B[NUM_TRANSITIONS][NUM_ROTATIONS], // boundary patch (4 rotations)
|
B, // boundary patch (4 rotations)
|
||||||
C[NUM_TRANSITIONS][NUM_ROTATIONS], // corner patch (4 rotations)
|
C, // corner patch (4 rotations)
|
||||||
G, // gregory patch
|
G, // gregory patch
|
||||||
GB, // gregory boundary patch
|
GB, // gregory boundary patch
|
||||||
GP; // gregory basis patch
|
GP; // gregory basis patch
|
||||||
|
|
||||||
PatchTypes() { std::memset(this, 0, sizeof(PatchTypes<TYPE>)); }
|
PatchTypes() { std::memset(this, 0, sizeof(PatchTypes<TYPE>)); }
|
||||||
|
|
||||||
// Returns the number of patches based on the patch type in the descriptor
|
// Returns the number of patches based on the patch type in the descriptor
|
||||||
TYPE & getValue( Far::PatchDescriptor desc ) {
|
TYPE & getValue( Far::PatchDescriptor desc ) {
|
||||||
switch (desc.GetType()) {
|
switch (desc.GetType()) {
|
||||||
case Far::PatchDescriptor::REGULAR : return R[desc.GetPattern()];
|
case Far::PatchDescriptor::REGULAR : return R;
|
||||||
case Far::PatchDescriptor::SINGLE_CREASE : return S[desc.GetPattern()][desc.GetRotation()];
|
case Far::PatchDescriptor::SINGLE_CREASE : return S;
|
||||||
case Far::PatchDescriptor::BOUNDARY : return B[desc.GetPattern()][desc.GetRotation()];
|
case Far::PatchDescriptor::BOUNDARY : return B;
|
||||||
case Far::PatchDescriptor::CORNER : return C[desc.GetPattern()][desc.GetRotation()];
|
case Far::PatchDescriptor::CORNER : return C;
|
||||||
case Far::PatchDescriptor::GREGORY : return G;
|
case Far::PatchDescriptor::GREGORY : return G;
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY : return GB;
|
case Far::PatchDescriptor::GREGORY_BOUNDARY : return GB;
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS : return GP;
|
case Far::PatchDescriptor::GREGORY_BASIS : return GP;
|
||||||
default : assert(0);
|
default : assert(0);
|
||||||
}
|
}
|
||||||
// can't be reached (suppress compiler warning)
|
// can't be reached (suppress compiler warning)
|
||||||
return R[0];
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counts the number of arrays required to store each type of patch used
|
// Counts the number of arrays required to store each type of patch used
|
||||||
// in the primitive
|
// in the primitive
|
||||||
int getNumPatchArrays() const {
|
int getNumPatchArrays() const {
|
||||||
int result=0;
|
int result=0;
|
||||||
for (int i=0; i<6; ++i) {
|
if (R) ++result;
|
||||||
|
if (S) ++result;
|
||||||
if (R[i]) ++result;
|
if (B) ++result;
|
||||||
|
if (C) ++result;
|
||||||
for (int j=0; j<4; ++j) {
|
|
||||||
if (S[i][j]) ++result;
|
|
||||||
if (B[i][j]) ++result;
|
|
||||||
if (C[i][j]) ++result;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (G) ++result;
|
if (G) ++result;
|
||||||
if (GB) ++result;
|
if (GB) ++result;
|
||||||
if (GP) ++result;
|
if (GP) ++result;
|
||||||
@ -94,11 +85,7 @@ struct PatchTypes {
|
|||||||
|
|
||||||
// Returns true if there's any single-crease patch
|
// Returns true if there's any single-crease patch
|
||||||
bool hasSingleCreasedPatches() const {
|
bool hasSingleCreasedPatches() const {
|
||||||
for (int i=0; i<6; ++i) {
|
if (S) return true;
|
||||||
for (int j=0; j<4; ++j) {
|
|
||||||
if (S[i][j]) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -127,25 +114,11 @@ typedef PatchTypes<Far::Index **> PatchFVarPointers;
|
|||||||
// branching on the edges or vertices.
|
// branching on the edges or vertices.
|
||||||
//
|
//
|
||||||
struct PatchFaceTag {
|
struct PatchFaceTag {
|
||||||
public:
|
|
||||||
// The HBR_ADAPTIVE TransitionType from <hbr/face.h> -- now named to more clearly
|
|
||||||
// reflect the number and orientation of transitional edges. Note that the values
|
|
||||||
// assigned here need to match the intended purpose to remain consistent with Hbr:
|
|
||||||
enum TransitionType {
|
|
||||||
NONE = 0,
|
|
||||||
TRANS_ONE = 1,
|
|
||||||
TRANS_TWO_ADJ = 2,
|
|
||||||
TRANS_THREE = 3,
|
|
||||||
TRANS_ALL = 4,
|
|
||||||
TRANS_TWO_OPP = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int _hasPatch : 1;
|
unsigned int _hasPatch : 1;
|
||||||
unsigned int _isRegular : 1;
|
unsigned int _isRegular : 1;
|
||||||
unsigned int _isTransitional : 1;
|
unsigned int _transitionMask : 4;
|
||||||
unsigned int _transitionType : 3;
|
unsigned int _boundaryMask : 4;
|
||||||
unsigned int _transitionRot : 2;
|
|
||||||
unsigned int _boundaryIndex : 2;
|
unsigned int _boundaryIndex : 2;
|
||||||
unsigned int _boundaryCount : 3;
|
unsigned int _boundaryCount : 3;
|
||||||
unsigned int _hasBoundaryEdge : 3;
|
unsigned int _hasBoundaryEdge : 3;
|
||||||
@ -166,6 +139,7 @@ public:
|
|||||||
// it ourselves?
|
// it ourselves?
|
||||||
//
|
//
|
||||||
_hasBoundaryEdge = true;
|
_hasBoundaryEdge = true;
|
||||||
|
_boundaryMask = boundaryEdgeMask;
|
||||||
|
|
||||||
switch (boundaryEdgeMask) {
|
switch (boundaryEdgeMask) {
|
||||||
case 0x0: _boundaryCount = 0, _boundaryIndex = 0, _hasBoundaryEdge = false; break; // no boundaries
|
case 0x0: _boundaryCount = 0, _boundaryIndex = 0, _hasBoundaryEdge = false; break; // no boundaries
|
||||||
@ -200,6 +174,7 @@ public:
|
|||||||
// and assert for all other cases.
|
// and assert for all other cases.
|
||||||
//
|
//
|
||||||
assert(_hasBoundaryEdge == false);
|
assert(_hasBoundaryEdge == false);
|
||||||
|
_boundaryMask = boundaryVertexMask;
|
||||||
|
|
||||||
switch (boundaryVertexMask) {
|
switch (boundaryVertexMask) {
|
||||||
case 0x0: _boundaryCount = 0; break; // no boundaries
|
case 0x0: _boundaryCount = 0; break; // no boundaries
|
||||||
@ -222,140 +197,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignTransitionRotationForCorner(int transitionEdgeMask) {
|
|
||||||
//
|
|
||||||
// Corner transition patches have only two interior edges that may be transitional.
|
|
||||||
//
|
|
||||||
// Either both are transitional (TRANS_TWO_ADJ) with only a single possible orientation,
|
|
||||||
// or only one is transitional (TRANS_ONE) with two possibilities. The former case is
|
|
||||||
// trivial. For the latter, use the known corner index to identify one of the two
|
|
||||||
// possible transition masks and test to determine between the two cases.
|
|
||||||
//
|
|
||||||
if (_transitionType == TRANS_ONE) {
|
|
||||||
int const edgeMaskPerCorner[] = { 4, 8, 1, 2 };
|
|
||||||
|
|
||||||
_transitionRot = 1 + (edgeMaskPerCorner[_boundaryIndex] != transitionEdgeMask);
|
|
||||||
} else {
|
|
||||||
_transitionRot = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assignTransitionRotationForBoundary(int transitionEdgeMask) {
|
|
||||||
//
|
|
||||||
// Boundary transition patches have three interior edges that may be transitional.
|
|
||||||
//
|
|
||||||
// The case of all three transitional (TRANS_THREE) has only one orientation, while the
|
|
||||||
// case of two opposite transitional edges (TRANS_TWO_OPP) also has only one orientation.
|
|
||||||
// So both of these are trivially handled.
|
|
||||||
//
|
|
||||||
// The case of a single transitional edge (TRANS_ONE) or one transitional edge (TRANS_TWO_ADJ)
|
|
||||||
// both have multiple orientations -- three for TRANS_ONE and two for TRANS_TWO_ADJ. Each is
|
|
||||||
// handled separately:
|
|
||||||
//
|
|
||||||
if (_transitionType == TRANS_ONE) {
|
|
||||||
if (transitionEdgeMask == (1 << ((_boundaryIndex + 2) % 4))) {
|
|
||||||
_transitionRot = 2;
|
|
||||||
} else if (transitionEdgeMask == (1 << ((_boundaryIndex + 1) % 4))) {
|
|
||||||
_transitionRot = 1;
|
|
||||||
} else {
|
|
||||||
_transitionRot = 3;
|
|
||||||
}
|
|
||||||
// XXXX manuelk mirror this rotation to match shader idiosyncracies
|
|
||||||
_transitionRot = (4-_transitionRot)%4;
|
|
||||||
} else if (_transitionType == TRANS_TWO_ADJ) {
|
|
||||||
int const edgeMaskPerBoundary[] = { 6, 12, 9, 3 };
|
|
||||||
_transitionRot = 1 + (edgeMaskPerBoundary[_boundaryIndex] == transitionEdgeMask);
|
|
||||||
} else if (_transitionType == TRANS_THREE) {
|
|
||||||
_transitionRot = 0;
|
|
||||||
} else {
|
|
||||||
_transitionRot = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assignTransitionRotationForSingleCrease(int transitionEdgeMask) {
|
|
||||||
//
|
|
||||||
// Single crease transition patches.
|
|
||||||
//
|
|
||||||
// rotate edgemask by boundaryIndex to align the creased edge
|
|
||||||
//
|
|
||||||
transitionEdgeMask = ((transitionEdgeMask >> _boundaryIndex) |
|
|
||||||
(transitionEdgeMask << (4-_boundaryIndex))) % 16;
|
|
||||||
|
|
||||||
/*
|
|
||||||
edgemask type : rotation to match to shader
|
|
||||||
0000 0 : NONE : 0
|
|
||||||
0001 1 : ONE : 0
|
|
||||||
0010 2 : ONE : 3
|
|
||||||
0011 3 : TWO_ADJ : 3
|
|
||||||
0100 4 : ONE : 2
|
|
||||||
0101 5 : TWO_OPP : 0
|
|
||||||
0110 6 : TWO_ADJ : 2
|
|
||||||
0111 7 : THREE : 1 (needs verify)
|
|
||||||
1000 8 : ONE : 1
|
|
||||||
1001 9 : TWO_ADJ : 0
|
|
||||||
1010 10 : TWO_OPP : 1
|
|
||||||
1011 11 : THREE : 2 (needs verify)
|
|
||||||
1100 12 : TWO_ADJ : 1
|
|
||||||
1101 13 : THREE : 3
|
|
||||||
1110 14 : THREE : 0 (needs verify)
|
|
||||||
1111 15 : ALL : 0
|
|
||||||
*/
|
|
||||||
static int transitionRots[16] = {0, 0, 3, 3, 2, 0, 2, 1, 1, 0, 1, 2, 1, 3, 0, 0 };
|
|
||||||
|
|
||||||
_transitionRot = transitionRots[transitionEdgeMask];
|
|
||||||
}
|
|
||||||
|
|
||||||
void assignTransitionPropertiesFromEdgeMask(int transitionEdgeMask) {
|
void assignTransitionPropertiesFromEdgeMask(int transitionEdgeMask) {
|
||||||
//
|
_transitionMask = transitionEdgeMask;
|
||||||
// Note the transition rotations will be a function of the boundary rotations, and
|
|
||||||
// so boundary rotations/index should have been previously assigned:
|
|
||||||
//
|
|
||||||
// As with the boundary rotation case, consider retrieving values from static 16-
|
|
||||||
// entry lookup tables if possible (depending on the function involving boundary
|
|
||||||
// rotations)...
|
|
||||||
//
|
|
||||||
_isTransitional = (transitionEdgeMask != 0);
|
|
||||||
|
|
||||||
switch (transitionEdgeMask) {
|
|
||||||
case 0x0: _transitionType = NONE; break; // no transitions
|
|
||||||
case 0x1: _transitionType = TRANS_ONE; break; // single edge 0
|
|
||||||
case 0x2: _transitionType = TRANS_ONE; break; // single edge 1
|
|
||||||
case 0x3: _transitionType = TRANS_TWO_ADJ; break; // two adjacent edges, 0 and 1
|
|
||||||
case 0x4: _transitionType = TRANS_ONE; break; // single edge 2
|
|
||||||
case 0x5: _transitionType = TRANS_TWO_OPP; break; // two opposite edges, 0 and 2
|
|
||||||
case 0x6: _transitionType = TRANS_TWO_ADJ; break; // two adjacent edges, 1 and 2
|
|
||||||
case 0x7: _transitionType = TRANS_THREE; break; // three edges, all but 3
|
|
||||||
case 0x8: _transitionType = TRANS_ONE; break; // single edge 3
|
|
||||||
case 0x9: _transitionType = TRANS_TWO_ADJ; break; // two adjacent edges, 3 and 0
|
|
||||||
case 0xa: _transitionType = TRANS_TWO_OPP; break; // two opposite edges, 1 and 3
|
|
||||||
case 0xb: _transitionType = TRANS_THREE; break; // three edges, all but 2
|
|
||||||
case 0xc: _transitionType = TRANS_TWO_ADJ; break; // two adjacent edges, 2 and 3
|
|
||||||
case 0xd: _transitionType = TRANS_THREE; break; // three edges, all but 1
|
|
||||||
case 0xe: _transitionType = TRANS_THREE; break; // three edges, all but 0
|
|
||||||
case 0xf: _transitionType = TRANS_ALL; break; // all edges
|
|
||||||
default: assert(false); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// May need another switch/lookup table here or combine it with the above -- the
|
|
||||||
// results below are a function of both transition and boundary properties...
|
|
||||||
if (transitionEdgeMask == 0) {
|
|
||||||
_transitionRot = 0;
|
|
||||||
} else if (_boundaryCount == 0 and _isSingleCrease) {
|
|
||||||
assignTransitionRotationForSingleCrease(transitionEdgeMask);
|
|
||||||
} else if (_boundaryCount == 0) {
|
|
||||||
// XXXX manuelk Rotations are mostly a direct map of the transitionEdgeMask
|
|
||||||
// Except for:
|
|
||||||
// - TRANS_TWO_ADJ that has rotation { 1, 2, 0, 3 }
|
|
||||||
// - TRANS_THREE that has rotation { 3, 2, 1, 0 }
|
|
||||||
// (matching shader idiosyncracies)
|
|
||||||
static unsigned char transitionRots[16] = {0, 0, 1, 1, 2, 0, 2, 3, 3, 0, 1, 2, 3, 1, 0, 0};
|
|
||||||
|
|
||||||
_transitionRot = transitionRots[transitionEdgeMask];
|
|
||||||
} else if (_boundaryCount == 1) {
|
|
||||||
assignTransitionRotationForBoundary(transitionEdgeMask);
|
|
||||||
} else if (_boundaryCount == 2) {
|
|
||||||
assignTransitionRotationForCorner(transitionEdgeMask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -372,7 +215,11 @@ offsetAndPermuteIndices(Far::Index const indices[], int count,
|
|||||||
|
|
||||||
if (permutation) {
|
if (permutation) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
result[i] = offset + indices[permutation[i]];
|
if (permutation[i] < 0) { // XXXdyu-patch-drawing
|
||||||
|
result[i] = offset + indices[0]; // XXXdyu-patch-drawing
|
||||||
|
} else {
|
||||||
|
result[i] = offset + indices[permutation[i]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (offset) {
|
} else if (offset) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
@ -847,9 +694,9 @@ PatchTablesFactory::gatherFVarData(AdaptiveContext & context, int level,
|
|||||||
// a pointer to the next descriptor
|
// a pointer to the next descriptor
|
||||||
//
|
//
|
||||||
PatchParam *
|
PatchParam *
|
||||||
PatchTablesFactory::computePatchParam(TopologyRefiner const & refiner,
|
PatchTablesFactory::computePatchParam(
|
||||||
int depth, Vtr::Index faceIndex, int rotation,
|
TopologyRefiner const & refiner, int depth, Vtr::Index faceIndex,
|
||||||
PatchParam *coord) {
|
int rotation, int boundaryMask, int transitionMask, PatchParam *coord) {
|
||||||
|
|
||||||
if (coord == NULL) return NULL;
|
if (coord == NULL) return NULL;
|
||||||
|
|
||||||
@ -899,7 +746,11 @@ PatchTablesFactory::computePatchParam(TopologyRefiner const & refiner,
|
|||||||
--depth;
|
--depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
coord->Set(ptexIndex, (short)u, (short)v, (unsigned char) rotation, (unsigned char) depth, nonquad);
|
boundaryMask = ((((boundaryMask << 4) | boundaryMask) >> rotation)) & 0xf;
|
||||||
|
transitionMask = ((((transitionMask << 4) | transitionMask) >> rotation)) & 0xf;
|
||||||
|
|
||||||
|
coord->Set(ptexIndex, (short)u, (short)v, (unsigned char) depth, nonquad,
|
||||||
|
(unsigned short) boundaryMask, (unsigned short) transitionMask);
|
||||||
|
|
||||||
return ++coord;
|
return ++coord;
|
||||||
}
|
}
|
||||||
@ -1102,7 +953,7 @@ PatchTablesFactory::createUniform(TopologyRefiner const & refiner, Options optio
|
|||||||
|
|
||||||
tables->reservePatchArrays(nlevels);
|
tables->reservePatchArrays(nlevels);
|
||||||
|
|
||||||
PatchDescriptor desc(ptype, PatchDescriptor::NON_TRANSITION, 0);
|
PatchDescriptor desc(ptype);
|
||||||
|
|
||||||
// generate patch arrays
|
// generate patch arrays
|
||||||
for (int level=firstlevel, poffset=0, voffset=0; level<=maxlevel; ++level) {
|
for (int level=firstlevel, poffset=0, voffset=0; level<=maxlevel; ++level) {
|
||||||
@ -1170,7 +1021,7 @@ PatchTablesFactory::createUniform(TopologyRefiner const & refiner, Options optio
|
|||||||
*iptr++ = levelVertOffset + fverts[vert];
|
*iptr++ = levelVertOffset + fverts[vert];
|
||||||
}
|
}
|
||||||
|
|
||||||
pptr = computePatchParam(refiner, level, face, /*rot*/0, pptr);
|
pptr = computePatchParam(refiner, level, face, /*rot*/0, /*boundary*/0, /*transition*/0, pptr);
|
||||||
|
|
||||||
if (generateFVarPatches) {
|
if (generateFVarPatches) {
|
||||||
for (fvc=fvc.begin(); fvc!=fvc.end(); ++fvc) {
|
for (fvc=fvc.begin(); fvc!=fvc.end(); ++fvc) {
|
||||||
@ -1508,17 +1359,15 @@ PatchTablesFactory::identifyAdaptivePatches(AdaptiveContext & context) {
|
|||||||
patchTag.assignTransitionPropertiesFromEdgeMask(refinedFaceTag._transitional);
|
patchTag.assignTransitionPropertiesFromEdgeMask(refinedFaceTag._transitional);
|
||||||
|
|
||||||
if (patchTag._isRegular) {
|
if (patchTag._isRegular) {
|
||||||
int transIndex = patchTag._transitionType;
|
|
||||||
int transRot = patchTag._transitionRot;
|
|
||||||
|
|
||||||
if (!patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
if (!patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
||||||
context.patchInventory.R[transIndex]++;
|
context.patchInventory.R++;
|
||||||
} else if (patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
} else if (patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
||||||
context.patchInventory.S[transIndex][transRot]++;
|
context.patchInventory.S++;
|
||||||
} else if (patchTag._boundaryCount == 1) {
|
} else if (patchTag._boundaryCount == 1) {
|
||||||
context.patchInventory.B[transIndex][transRot]++;
|
context.patchInventory.R++;
|
||||||
} else {
|
} else {
|
||||||
context.patchInventory.C[transIndex][transRot]++;
|
context.patchInventory.R++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if end-cap patches use a stencils-driven basis, we don't need
|
// if end-cap patches use a stencils-driven basis, we don't need
|
||||||
@ -1679,21 +1528,21 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
if (patchTag._isRegular) {
|
if (patchTag._isRegular) {
|
||||||
Index patchVerts[16];
|
Index patchVerts[16];
|
||||||
|
|
||||||
int tIndex = patchTag._transitionType;
|
|
||||||
int rIndex = patchTag._transitionRot;
|
|
||||||
int bIndex = patchTag._boundaryIndex;
|
int bIndex = patchTag._boundaryIndex;
|
||||||
|
int boundaryMask = patchTag._boundaryMask;
|
||||||
|
int transitionMask = patchTag._transitionMask;
|
||||||
|
|
||||||
if (!patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
if (!patchTag._isSingleCrease and patchTag._boundaryCount == 0) {
|
||||||
int const permuteInterior[16] = { 5, 6, 7, 8, 4, 0, 1, 9, 15, 3, 2, 10, 14, 13, 12, 11 };
|
int const permuteInterior[16] = { 5, 6, 7, 8, 4, 0, 1, 9, 15, 3, 2, 10, 14, 13, 12, 11 };
|
||||||
|
|
||||||
level->gatherQuadRegularInteriorPatchPoints(faceIndex, patchVerts, rIndex);
|
level->gatherQuadRegularInteriorPatchPoints(faceIndex, patchVerts, /*rotation*/0);
|
||||||
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteInterior, iptrs.R[tIndex]);
|
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteInterior, iptrs.R);
|
||||||
|
|
||||||
iptrs.R[tIndex] += 16;
|
iptrs.R += 16;
|
||||||
pptrs.R[tIndex] = computePatchParam(refiner, i, faceIndex, rIndex, pptrs.R[tIndex]);
|
pptrs.R = computePatchParam(refiner, i, faceIndex, /*rotation*/0, /*boundary*/0, transitionMask, pptrs.R);
|
||||||
|
|
||||||
fofss.R[tIndex] += gatherFVarData(context,
|
fofss.R += gatherFVarData(context,
|
||||||
i, faceIndex, levelFaceOffset, rIndex, levelFVarVertOffsets, fofss.R[tIndex], fptrs.R[tIndex]);
|
i, faceIndex, levelFaceOffset, /*rotation*/0, levelFVarVertOffsets, fofss.R, fptrs.R);
|
||||||
} else {
|
} else {
|
||||||
// For the boundary and corner cases, the Hbr code makes some adjustments to the
|
// For the boundary and corner cases, the Hbr code makes some adjustments to the
|
||||||
// rotations here from the way they were defined earlier. That raises questions
|
// rotations here from the way they were defined earlier. That raises questions
|
||||||
@ -1717,42 +1566,42 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
if (patchTag._isSingleCrease and patchTag._boundaryCount==0) {
|
if (patchTag._isSingleCrease and patchTag._boundaryCount==0) {
|
||||||
int const permuteInterior[16] = { 5, 6, 7, 8, 4, 0, 1, 9, 15, 3, 2, 10, 14, 13, 12, 11 };
|
int const permuteInterior[16] = { 5, 6, 7, 8, 4, 0, 1, 9, 15, 3, 2, 10, 14, 13, 12, 11 };
|
||||||
level->gatherQuadRegularInteriorPatchPoints(faceIndex, patchVerts, bIndex);
|
level->gatherQuadRegularInteriorPatchPoints(faceIndex, patchVerts, bIndex);
|
||||||
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteInterior, iptrs.S[tIndex][rIndex]);
|
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteInterior, iptrs.S);
|
||||||
|
|
||||||
int creaseEdge = (bIndex+2)%4;
|
int creaseEdge = (bIndex+2)%4;
|
||||||
float sharpness = level->getEdgeSharpness((level->getFaceEdges(faceIndex)[creaseEdge]));
|
float sharpness = level->getEdgeSharpness((level->getFaceEdges(faceIndex)[creaseEdge]));
|
||||||
sharpness = std::min(sharpness, (float)(context.options.maxIsolationLevel-i));
|
sharpness = std::min(sharpness, (float)(context.options.maxIsolationLevel-i));
|
||||||
|
|
||||||
iptrs.S[tIndex][rIndex] += 16;
|
iptrs.S += 16;
|
||||||
pptrs.S[tIndex][rIndex] = computePatchParam(refiner, i, faceIndex, bIndex, pptrs.S[tIndex][rIndex]);
|
pptrs.S = computePatchParam(refiner, i, faceIndex, bIndex, /*boundary*/0, transitionMask, pptrs.S);
|
||||||
*sptrs.S[tIndex][rIndex]++ = assignSharpnessIndex(sharpness, tables->_sharpnessValues);
|
*sptrs.S++ = assignSharpnessIndex(sharpness, tables->_sharpnessValues);
|
||||||
|
|
||||||
fofss.S[tIndex][rIndex] += gatherFVarData(context,
|
fofss.S += gatherFVarData(context,
|
||||||
i, faceIndex, levelFaceOffset, bIndex, levelFVarVertOffsets, fofss.S[tIndex][rIndex], fptrs.S[tIndex][rIndex]);
|
i, faceIndex, levelFaceOffset, bIndex, levelFVarVertOffsets, fofss.S, fptrs.S);
|
||||||
} else if (patchTag._boundaryCount == 1) {
|
} else if (patchTag._boundaryCount == 1) {
|
||||||
int const permuteBoundary[12] = { 11, 3, 0, 4, 10, 2, 1, 5, 9, 8, 7, 6 };
|
int const permuteBoundary[16] = { -1, 4, 5, 6, -1, 0, 1, 7, -1, 3, 2, 8, -1, 11, 10, 9 };
|
||||||
|
|
||||||
level->gatherQuadRegularBoundaryPatchPoints(faceIndex, patchVerts, bIndex);
|
level->gatherQuadRegularBoundaryPatchPoints(faceIndex, patchVerts, bIndex);
|
||||||
offsetAndPermuteIndices(patchVerts, 12, levelVertOffset, permuteBoundary, iptrs.B[tIndex][rIndex]);
|
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteBoundary, iptrs.R);
|
||||||
|
|
||||||
iptrs.B[tIndex][rIndex] += 12;
|
bIndex = 3*((bIndex+1)&1);
|
||||||
pptrs.B[tIndex][rIndex] = computePatchParam(refiner, i, faceIndex, bIndex, pptrs.B[tIndex][rIndex]);
|
|
||||||
|
|
||||||
fofss.B[tIndex][rIndex] += gatherFVarData(context,
|
iptrs.R += 16;
|
||||||
i, faceIndex, levelFaceOffset, bIndex, levelFVarVertOffsets, fofss.B[tIndex][rIndex], fptrs.B[tIndex][rIndex]);
|
pptrs.R = computePatchParam(refiner, i, faceIndex, bIndex, boundaryMask, transitionMask, pptrs.R);
|
||||||
|
|
||||||
|
fofss.R += gatherFVarData(context,
|
||||||
|
i, faceIndex, levelFaceOffset, /*rotation*/0, levelFVarVertOffsets, fofss.R, fptrs.R);
|
||||||
} else {
|
} else {
|
||||||
int const permuteCorner[9] = { 8, 3, 0, 7, 2, 1, 6, 5, 4 };
|
int const permuteCorner[16] = { -1, -1, -1, -1, -1, 0, 1, 4, -1, 3, 2, 5, -1, 8, 7, 6 };
|
||||||
|
|
||||||
level->gatherQuadRegularCornerPatchPoints(faceIndex, patchVerts, bIndex);
|
level->gatherQuadRegularCornerPatchPoints(faceIndex, patchVerts, bIndex);
|
||||||
offsetAndPermuteIndices(patchVerts, 9, levelVertOffset, permuteCorner, iptrs.C[tIndex][rIndex]);
|
offsetAndPermuteIndices(patchVerts, 16, levelVertOffset, permuteCorner, iptrs.R);
|
||||||
|
|
||||||
bIndex = (bIndex+3)%4;
|
iptrs.R += 16;
|
||||||
|
pptrs.R = computePatchParam(refiner, i, faceIndex, bIndex, boundaryMask, transitionMask, pptrs.R);
|
||||||
|
|
||||||
iptrs.C[tIndex][rIndex] += 9;
|
fofss.R += gatherFVarData(context,
|
||||||
pptrs.C[tIndex][rIndex] = computePatchParam(refiner, i, faceIndex, bIndex, pptrs.C[tIndex][rIndex]);
|
i, faceIndex, levelFaceOffset, /*rotation*/0, levelFVarVertOffsets, fofss.R, fptrs.R);
|
||||||
|
|
||||||
fofss.C[tIndex][rIndex] += gatherFVarData(context,
|
|
||||||
i, faceIndex, levelFaceOffset, bIndex, levelFVarVertOffsets, fofss.C[tIndex][rIndex], fptrs.C[tIndex][rIndex]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1779,7 +1628,7 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
|
|
||||||
++numGregoryBasisPatches;
|
++numGregoryBasisPatches;
|
||||||
|
|
||||||
pptrs.GP = computePatchParam(refiner, i, faceIndex, 0, pptrs.GP);
|
pptrs.GP = computePatchParam(refiner, i, faceIndex, 0, /*boundary*/0, /*transition*/0, pptrs.GP);
|
||||||
|
|
||||||
fofss.GP += gatherFVarData(context,
|
fofss.GP += gatherFVarData(context,
|
||||||
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.GP, fptrs.GP);
|
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.GP, fptrs.GP);
|
||||||
@ -1796,7 +1645,7 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
getQuadOffsets(*level, faceIndex, quad_G_C0_P);
|
getQuadOffsets(*level, faceIndex, quad_G_C0_P);
|
||||||
quad_G_C0_P += 4;
|
quad_G_C0_P += 4;
|
||||||
|
|
||||||
pptrs.G = computePatchParam(refiner, i, faceIndex, 0, pptrs.G);
|
pptrs.G = computePatchParam(refiner, i, faceIndex, 0, /*boundary*/0, /*transition*/0, pptrs.G);
|
||||||
|
|
||||||
fofss.G += gatherFVarData(context,
|
fofss.G += gatherFVarData(context,
|
||||||
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.G, fptrs.G);
|
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.G, fptrs.G);
|
||||||
@ -1814,7 +1663,7 @@ PatchTablesFactory::populateAdaptivePatches(AdaptiveContext & context) {
|
|||||||
|
|
||||||
//int bIndex = (patchTag._boundaryIndex+1)%4;
|
//int bIndex = (patchTag._boundaryIndex+1)%4;
|
||||||
|
|
||||||
pptrs.GB = computePatchParam(refiner, i, faceIndex, 0, pptrs.GB);
|
pptrs.GB = computePatchParam(refiner, i, faceIndex, 0, /*boundary*/0, /*transition*/0, pptrs.GB);
|
||||||
|
|
||||||
fofss.GB += gatherFVarData(context,
|
fofss.GB += gatherFVarData(context,
|
||||||
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.GB, fptrs.GB);
|
i, faceIndex, levelFaceOffset, 0, levelFVarVertOffsets, fofss.GB, fptrs.GB);
|
||||||
|
@ -126,7 +126,8 @@ private:
|
|||||||
Options options, int npatches, PatchTables * tables);
|
Options options, int npatches, PatchTables * tables);
|
||||||
|
|
||||||
static PatchParam * computePatchParam(TopologyRefiner const & refiner,
|
static PatchParam * computePatchParam(TopologyRefiner const & refiner,
|
||||||
int level, int face, int rotation, PatchParam * coord);
|
int level, int face, int rotation,
|
||||||
|
int boundaryMask, int transitionMask, PatchParam * coord);
|
||||||
|
|
||||||
static int gatherFVarData(AdaptiveContext & state,
|
static int gatherFVarData(AdaptiveContext & state,
|
||||||
int level, Index faceIndex, Index levelFaceOffset, int rotation, Index const * levelOffsets, Index fofss, Index ** fptrs);
|
int level, Index faceIndex, Index levelFaceOffset, int rotation, Index const * levelOffsets, Index fofss, Index ** fptrs);
|
||||||
|
@ -84,122 +84,67 @@ D3D11DrawRegistryBase::_CreateDrawSourceConfig(
|
|||||||
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.GetPattern() == Far::PatchDescriptor::NON_TRANSITION) {
|
switch (desc.GetType()) {
|
||||||
switch (desc.GetType()) {
|
case Far::PatchDescriptor::REGULAR:
|
||||||
case Far::PatchDescriptor::REGULAR:
|
case Far::PatchDescriptor::BOUNDARY:
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
case Far::PatchDescriptor::CORNER:
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->hullShader.source = bsplineShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->domainShader.source = bsplineShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::SINGLE_CREASE:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->hullShader.source = bsplineShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
|
||||||
sconfig->domainShader.source = bsplineShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
sconfig->domainShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::BOUNDARY:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->hullShader.source = bsplineShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_BOUNDARY");
|
|
||||||
sconfig->domainShader.source = bsplineShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::CORNER:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->hullShader.source = bsplineShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_CORNER");
|
|
||||||
sconfig->domainShader.source = bsplineShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::GREGORY:
|
|
||||||
sconfig->vertexShader.source = gregoryShaderSource;
|
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->hullShader.source = gregoryShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->domainShader.source = gregoryShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
|
||||||
sconfig->vertexShader.source = gregoryShaderSource;
|
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
sconfig->hullShader.source = gregoryShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
sconfig->domainShader.source = gregoryShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
|
||||||
sconfig->domainShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
break;
|
|
||||||
default: // POINTS, LINES, QUADS, TRIANGLES
|
|
||||||
// do nothing
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { // pattern != NON_TRANSITION
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
sconfig->vertexShader.source = bsplineShaderSource;
|
||||||
sconfig->vertexShader.target = "vs_5_0";
|
sconfig->vertexShader.target = "vs_5_0";
|
||||||
sconfig->vertexShader.entry = "vs_main_patches";
|
sconfig->vertexShader.entry = "vs_main_patches";
|
||||||
sconfig->hullShader.source =
|
sconfig->hullShader.source = bsplineShaderSource;
|
||||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
|
||||||
sconfig->hullShader.target = "hs_5_0";
|
sconfig->hullShader.target = "hs_5_0";
|
||||||
sconfig->hullShader.entry = "hs_main_patches";
|
sconfig->hullShader.entry = "hs_main_patches";
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_TRANSITION");
|
sconfig->domainShader.source = bsplineShaderSource;
|
||||||
sconfig->domainShader.source =
|
|
||||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
|
||||||
sconfig->domainShader.target = "ds_5_0";
|
sconfig->domainShader.target = "ds_5_0";
|
||||||
sconfig->domainShader.entry = "ds_main_patches";
|
sconfig->domainShader.entry = "ds_main_patches";
|
||||||
sconfig->domainShader.AddDefine("OSD_PATCH_TRANSITION");
|
break;
|
||||||
|
case Far::PatchDescriptor::SINGLE_CREASE:
|
||||||
int pattern = desc.GetPattern() - 1;
|
sconfig->commonShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
||||||
int rotation = desc.GetRotation();
|
sconfig->vertexShader.source = bsplineShaderSource;
|
||||||
int subpatch = desc.GetSubPatch();
|
sconfig->vertexShader.target = "vs_5_0";
|
||||||
|
sconfig->vertexShader.entry = "vs_main_patches";
|
||||||
std::ostringstream ss;
|
sconfig->hullShader.source = bsplineShaderSource;
|
||||||
ss << "OSD_TRANSITION_PATTERN" << pattern << subpatch;
|
sconfig->hullShader.target = "hs_5_0";
|
||||||
sconfig->hullShader.AddDefine(ss.str());
|
sconfig->hullShader.entry = "hs_main_patches";
|
||||||
sconfig->domainShader.AddDefine(ss.str());
|
sconfig->hullShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
||||||
|
sconfig->domainShader.source = bsplineShaderSource;
|
||||||
ss.str("");
|
sconfig->domainShader.target = "ds_5_0";
|
||||||
ss << rotation;
|
sconfig->domainShader.entry = "ds_main_patches";
|
||||||
sconfig->hullShader.AddDefine("OSD_TRANSITION_ROTATE", ss.str());
|
sconfig->domainShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
||||||
sconfig->domainShader.AddDefine("OSD_TRANSITION_ROTATE", ss.str());
|
break;
|
||||||
|
case Far::PatchDescriptor::GREGORY:
|
||||||
if (desc.GetType() == Far::PatchDescriptor::SINGLE_CREASE) {
|
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY");
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
sconfig->vertexShader.source = gregoryShaderSource;
|
||||||
sconfig->domainShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
sconfig->vertexShader.target = "vs_5_0";
|
||||||
} else if (desc.GetType() == Far::PatchDescriptor::BOUNDARY) {
|
sconfig->vertexShader.entry = "vs_main_patches";
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_BOUNDARY");
|
sconfig->hullShader.source = gregoryShaderSource;
|
||||||
} else if (desc.GetType() == Far::PatchDescriptor::CORNER) {
|
sconfig->hullShader.target = "hs_5_0";
|
||||||
sconfig->hullShader.AddDefine("OSD_PATCH_CORNER");
|
sconfig->hullShader.entry = "hs_main_patches";
|
||||||
}
|
sconfig->domainShader.source = gregoryShaderSource;
|
||||||
|
sconfig->domainShader.target = "ds_5_0";
|
||||||
|
sconfig->domainShader.entry = "ds_main_patches";
|
||||||
|
break;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
|
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
sconfig->vertexShader.source = gregoryShaderSource;
|
||||||
|
sconfig->vertexShader.target = "vs_5_0";
|
||||||
|
sconfig->vertexShader.entry = "vs_main_patches";
|
||||||
|
sconfig->vertexShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
sconfig->hullShader.source = gregoryShaderSource;
|
||||||
|
sconfig->hullShader.target = "hs_5_0";
|
||||||
|
sconfig->hullShader.entry = "hs_main_patches";
|
||||||
|
sconfig->hullShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
sconfig->domainShader.source = gregoryShaderSource;
|
||||||
|
sconfig->domainShader.target = "ds_5_0";
|
||||||
|
sconfig->domainShader.entry = "ds_main_patches";
|
||||||
|
sconfig->domainShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
break;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BOUNDARY_BASIS:
|
||||||
|
// XXXdyu-patch-drawing gregory basis for d3d11
|
||||||
|
break;
|
||||||
|
default: // POINTS, LINES, QUADS, TRIANGLES
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sconfig;
|
return sconfig;
|
||||||
|
@ -39,37 +39,21 @@ void
|
|||||||
DrawContext::ConvertPatchArrays(Far::PatchTables const &patchTables,
|
DrawContext::ConvertPatchArrays(Far::PatchTables const &patchTables,
|
||||||
PatchArrayVector &osdPatchArrays, int maxValence, int numElements) {
|
PatchArrayVector &osdPatchArrays, int maxValence, int numElements) {
|
||||||
|
|
||||||
// create patch arrays for drawing (while duplicating subpatches for transition patch arrays)
|
int narrays = patchTables.GetNumPatchArrays();
|
||||||
static int subPatchCounts[] = { 1, 3, 4, 4, 4, 2 }; // number of subpatches for patterns
|
|
||||||
|
|
||||||
int numTotalPatchArrays = 0;
|
|
||||||
for (int array=0; array < patchTables.GetNumPatchArrays(); ++array) {
|
|
||||||
|
|
||||||
Far::PatchDescriptor::TransitionPattern pattern =
|
|
||||||
patchTables.GetPatchArrayDescriptor(array).GetPattern();
|
|
||||||
|
|
||||||
numTotalPatchArrays += subPatchCounts[(int)pattern];
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate drawing patch arrays
|
// allocate drawing patch arrays
|
||||||
osdPatchArrays.clear();
|
osdPatchArrays.clear();
|
||||||
osdPatchArrays.reserve(numTotalPatchArrays);
|
osdPatchArrays.reserve(narrays);
|
||||||
|
|
||||||
int narrays = patchTables.GetNumPatchArrays();
|
|
||||||
for (int array=0, pidx=0, vidx=0, qidx=0; array<narrays; ++array) {
|
for (int array=0, pidx=0, vidx=0, qidx=0; array<narrays; ++array) {
|
||||||
|
|
||||||
Far::PatchDescriptor srcDesc = patchTables.GetPatchArrayDescriptor(array);
|
Far::PatchDescriptor srcDesc = patchTables.GetPatchArrayDescriptor(array);
|
||||||
|
|
||||||
int npatches = patchTables.GetNumPatches(array),
|
int npatches = patchTables.GetNumPatches(array),
|
||||||
nsubpatches = subPatchCounts[(int)srcDesc.GetPattern()],
|
|
||||||
nverts = srcDesc.GetNumControlVertices();
|
nverts = srcDesc.GetNumControlVertices();
|
||||||
|
|
||||||
for (int i = 0; i < nsubpatches; ++i) {
|
PatchDescriptor desc(srcDesc, maxValence, numElements);
|
||||||
|
osdPatchArrays.push_back(PatchArray(desc, npatches, vidx, pidx, qidx));
|
||||||
PatchDescriptor desc(srcDesc, maxValence, i, numElements);
|
|
||||||
|
|
||||||
osdPatchArrays.push_back(PatchArray(desc, npatches, vidx, pidx, qidx));
|
|
||||||
}
|
|
||||||
|
|
||||||
vidx += npatches * nverts;
|
vidx += npatches * nverts;
|
||||||
pidx += npatches;
|
pidx += npatches;
|
||||||
|
@ -68,17 +68,11 @@ public:
|
|||||||
///
|
///
|
||||||
/// @param maxValence Highest vertex valence in the primitive
|
/// @param maxValence Highest vertex valence in the primitive
|
||||||
///
|
///
|
||||||
/// @param subPatch Index of the triangulated sub-patch for the given
|
|
||||||
/// transition pattern. Transition patches need to be
|
|
||||||
/// split into multiple sub-patches in order to be
|
|
||||||
/// rendered with hardware tessellation.
|
|
||||||
///
|
|
||||||
/// @param numElements The size of the vertex and varying data per-vertex
|
/// @param numElements The size of the vertex and varying data per-vertex
|
||||||
/// (in floats)
|
/// (in floats)
|
||||||
///
|
///
|
||||||
PatchDescriptor(Far::PatchDescriptor farDesc, unsigned char maxValence,
|
PatchDescriptor(Far::PatchDescriptor farDesc, unsigned char maxValence, unsigned char numElements) :
|
||||||
unsigned char subPatch, unsigned char numElements) :
|
_farDesc(farDesc), _maxValence(maxValence), _numElements(numElements) { }
|
||||||
_farDesc(farDesc), _maxValence(maxValence), _subPatch(subPatch), _numElements(numElements) { }
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the type of the patch
|
/// Returns the type of the patch
|
||||||
@ -86,16 +80,6 @@ public:
|
|||||||
return _farDesc.GetType();
|
return _farDesc.GetType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transition pattern of the patch if any (5 types)
|
|
||||||
Far::PatchDescriptor::TransitionPattern GetPattern() const {
|
|
||||||
return _farDesc.GetPattern();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the rotation of the patch (4 rotations)
|
|
||||||
unsigned char GetRotation() const {
|
|
||||||
return _farDesc.GetRotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of control vertices expected for a patch of the
|
/// Returns the number of control vertices expected for a patch of the
|
||||||
/// type described
|
/// type described
|
||||||
int GetNumControlVertices() const {
|
int GetNumControlVertices() const {
|
||||||
@ -107,11 +91,6 @@ public:
|
|||||||
return _maxValence;
|
return _maxValence;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the subpatch id
|
|
||||||
int GetSubPatch() const {
|
|
||||||
return _subPatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of vertex elements
|
/// Returns the number of vertex elements
|
||||||
int GetNumElements() const {
|
int GetNumElements() const {
|
||||||
return _numElements;
|
return _numElements;
|
||||||
@ -131,7 +110,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
Far::PatchDescriptor _farDesc;
|
Far::PatchDescriptor _farDesc;
|
||||||
unsigned char _maxValence;
|
unsigned char _maxValence;
|
||||||
unsigned char _subPatch;
|
|
||||||
unsigned char _numElements;
|
unsigned char _numElements;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,9 +239,8 @@ inline bool
|
|||||||
DrawContext::PatchDescriptor::operator < ( PatchDescriptor const other ) const
|
DrawContext::PatchDescriptor::operator < ( PatchDescriptor const other ) const
|
||||||
{
|
{
|
||||||
return _farDesc < other._farDesc or (_farDesc == other._farDesc and
|
return _farDesc < other._farDesc or (_farDesc == other._farDesc and
|
||||||
(_subPatch < other._subPatch or ((_subPatch == other._subPatch) and
|
|
||||||
(_maxValence < other._maxValence or ((_maxValence == other._maxValence) and
|
(_maxValence < other._maxValence or ((_maxValence == other._maxValence) and
|
||||||
(_numElements < other._numElements))))));
|
(_numElements < other._numElements))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if the descriptors are identical
|
// True if the descriptors are identical
|
||||||
@ -271,7 +248,6 @@ inline bool
|
|||||||
DrawContext::PatchDescriptor::operator == ( PatchDescriptor const other ) const
|
DrawContext::PatchDescriptor::operator == ( PatchDescriptor const other ) const
|
||||||
{
|
{
|
||||||
return _farDesc == other._farDesc and
|
return _farDesc == other._farDesc and
|
||||||
_subPatch == other._subPatch and
|
|
||||||
_maxValence == other._maxValence and
|
_maxValence == other._maxValence and
|
||||||
_numElements == other._numElements;
|
_numElements == other._numElements;
|
||||||
}
|
}
|
||||||
|
@ -84,133 +84,77 @@ GLDrawRegistryBase::_CreateDrawSourceConfig(
|
|||||||
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.GetPattern() == Far::PatchDescriptor::NON_TRANSITION) {
|
switch (desc.GetType()) {
|
||||||
switch (desc.GetType()) {
|
case Far::PatchDescriptor::REGULAR:
|
||||||
case Far::PatchDescriptor::REGULAR:
|
case Far::PatchDescriptor::BOUNDARY:
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
case Far::PatchDescriptor::CORNER:
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
sconfig->commonShader.AddDefine("OSD_PATCH_BSPLINE");
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
|
||||||
sconfig->tessEvalShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::SINGLE_CREASE:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
|
||||||
sconfig->tessEvalShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::BOUNDARY:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_BOUNDARY");
|
|
||||||
sconfig->tessEvalShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::CORNER:
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_CORNER");
|
|
||||||
sconfig->tessEvalShader.source = bsplineShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::GREGORY:
|
|
||||||
sconfig->vertexShader.source = gregoryShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
|
|
||||||
sconfig->tessControlShader.source = gregoryShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
|
|
||||||
sconfig->tessEvalShader.source = gregoryShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
|
||||||
sconfig->vertexShader.source = gregoryShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
sconfig->tessControlShader.source = gregoryShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
sconfig->tessEvalShader.source = gregoryShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
|
||||||
break;
|
|
||||||
case Far::PatchDescriptor::GREGORY_BASIS:
|
|
||||||
sconfig->vertexShader.source = gregoryBasisShaderSource;
|
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_BASIS_SHADER");
|
|
||||||
sconfig->tessControlShader.source = gregoryBasisShaderSource;
|
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_BASIS_SHADER");
|
|
||||||
sconfig->tessEvalShader.source = gregoryBasisShaderSource;
|
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_BASIS_SHADER");
|
|
||||||
break;
|
|
||||||
default: // POINTS, LINES, QUADS, TRIANGLES
|
|
||||||
// do nothing
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { // pattern != NON_TRANSITION
|
|
||||||
sconfig->vertexShader.source = bsplineShaderSource;
|
sconfig->vertexShader.source = bsplineShaderSource;
|
||||||
sconfig->vertexShader.version = "#version 410\n";
|
sconfig->vertexShader.version = "#version 410\n";
|
||||||
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
||||||
sconfig->tessControlShader.source =
|
sconfig->tessControlShader.source =
|
||||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||||
sconfig->tessControlShader.version = "#version 410\n";
|
sconfig->tessControlShader.version = "#version 410\n";
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_TRANSITION");
|
|
||||||
sconfig->tessEvalShader.source =
|
sconfig->tessEvalShader.source =
|
||||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||||
sconfig->tessEvalShader.version = "#version 410\n";
|
sconfig->tessEvalShader.version = "#version 410\n";
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TRANSITION");
|
break;
|
||||||
|
case Far::PatchDescriptor::SINGLE_CREASE:
|
||||||
int pattern = desc.GetPattern() - 1;
|
sconfig->commonShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
||||||
int rotation = desc.GetRotation();
|
sconfig->vertexShader.source = bsplineShaderSource;
|
||||||
int subpatch = desc.GetSubPatch();
|
sconfig->vertexShader.version = "#version 410\n";
|
||||||
|
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_BSPLINE_SHADER");
|
||||||
std::ostringstream ss;
|
sconfig->tessControlShader.source =
|
||||||
ss << "OSD_TRANSITION_PATTERN" << pattern << subpatch;
|
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||||
sconfig->tessControlShader.AddDefine(ss.str());
|
sconfig->tessControlShader.version = "#version 410\n";
|
||||||
sconfig->tessEvalShader.AddDefine(ss.str());
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER");
|
||||||
|
sconfig->tessEvalShader.source =
|
||||||
ss.str("");
|
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||||
ss << rotation;
|
sconfig->tessEvalShader.version = "#version 410\n";
|
||||||
sconfig->tessControlShader.AddDefine("OSD_TRANSITION_ROTATE", ss.str());
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_BSPLINE_SHADER");
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_TRANSITION_ROTATE", ss.str());
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
||||||
|
case Far::PatchDescriptor::GREGORY:
|
||||||
if (desc.GetType() == Far::PatchDescriptor::SINGLE_CREASE) {
|
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY");
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
sconfig->vertexShader.source = gregoryShaderSource;
|
||||||
sconfig->tessEvalShader.AddDefine("OSD_PATCH_SINGLE_CREASE");
|
sconfig->vertexShader.version = "#version 410\n";
|
||||||
} else if (desc.GetType() == Far::PatchDescriptor::BOUNDARY) {
|
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_BOUNDARY");
|
sconfig->tessControlShader.source = gregoryShaderSource;
|
||||||
} else if (desc.GetType() == Far::PatchDescriptor::CORNER) {
|
sconfig->tessControlShader.version = "#version 410\n";
|
||||||
sconfig->tessControlShader.AddDefine("OSD_PATCH_CORNER");
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
|
||||||
}
|
sconfig->tessEvalShader.source = gregoryShaderSource;
|
||||||
|
sconfig->tessEvalShader.version = "#version 410\n";
|
||||||
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
|
||||||
|
break;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BOUNDARY:
|
||||||
|
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
sconfig->vertexShader.source = gregoryShaderSource;
|
||||||
|
sconfig->vertexShader.version = "#version 410\n";
|
||||||
|
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_SHADER");
|
||||||
|
sconfig->tessControlShader.source = gregoryShaderSource;
|
||||||
|
sconfig->tessControlShader.version = "#version 410\n";
|
||||||
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_SHADER");
|
||||||
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_GREGORY_BOUNDARY");
|
||||||
|
sconfig->tessEvalShader.source = gregoryShaderSource;
|
||||||
|
sconfig->tessEvalShader.version = "#version 410\n";
|
||||||
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_SHADER");
|
||||||
|
break;
|
||||||
|
case Far::PatchDescriptor::GREGORY_BASIS:
|
||||||
|
sconfig->commonShader.AddDefine("OSD_PATCH_GREGORY_BASIS");
|
||||||
|
sconfig->vertexShader.source = gregoryBasisShaderSource;
|
||||||
|
sconfig->vertexShader.version = "#version 410\n";
|
||||||
|
sconfig->vertexShader.AddDefine("OSD_PATCH_VERTEX_GREGORY_BASIS_SHADER");
|
||||||
|
sconfig->tessControlShader.source = gregoryBasisShaderSource;
|
||||||
|
sconfig->tessControlShader.version = "#version 410\n";
|
||||||
|
sconfig->tessControlShader.AddDefine("OSD_PATCH_TESS_CONTROL_GREGORY_BASIS_SHADER");
|
||||||
|
sconfig->tessEvalShader.source = gregoryBasisShaderSource;
|
||||||
|
sconfig->tessEvalShader.version = "#version 410\n";
|
||||||
|
sconfig->tessEvalShader.AddDefine("OSD_PATCH_TESS_EVAL_GREGORY_BASIS_SHADER");
|
||||||
|
break;
|
||||||
|
default: // POINTS, LINES, QUADS, TRIANGLES
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sconfig;
|
return sconfig;
|
||||||
|
@ -65,14 +65,6 @@ uniform mat4 Mi = mat4(
|
|||||||
0.f, 0.f, 1.f, 0.f
|
0.f, 0.f, 1.f, 0.f
|
||||||
);
|
);
|
||||||
|
|
||||||
// Boundary / Corner
|
|
||||||
uniform mat4x3 B = mat4x3(
|
|
||||||
1.f, 0.f, 0.f,
|
|
||||||
4.f/6.f, 2.f/6.f, 0.f,
|
|
||||||
2.f/6.f, 4.f/6.f, 0.f,
|
|
||||||
1.f/6.f, 4.f/6.f, 1.f/6.f
|
|
||||||
);
|
|
||||||
|
|
||||||
layout(vertices = 16) out;
|
layout(vertices = 16) out;
|
||||||
|
|
||||||
in block {
|
in block {
|
||||||
@ -92,6 +84,35 @@ out block {
|
|||||||
|
|
||||||
#define ID gl_InvocationID
|
#define ID gl_InvocationID
|
||||||
|
|
||||||
|
void
|
||||||
|
reflectBoundaryEdges(inout vec3 cpt[24], int patchParam)
|
||||||
|
{
|
||||||
|
if (((patchParam >> 4) & 1) != 0) {
|
||||||
|
cpt[0] = 2*cpt[4] - cpt[8];
|
||||||
|
cpt[1] = 2*cpt[5] - cpt[9];
|
||||||
|
cpt[2] = 2*cpt[6] - cpt[10];
|
||||||
|
cpt[3] = 2*cpt[7] - cpt[11];
|
||||||
|
}
|
||||||
|
if (((patchParam >> 4) & 2) != 0) {
|
||||||
|
cpt[3] = 2*cpt[2] - cpt[1];
|
||||||
|
cpt[7] = 2*cpt[6] - cpt[5];
|
||||||
|
cpt[11] = 2*cpt[10] - cpt[9];
|
||||||
|
cpt[15] = 2*cpt[14] - cpt[13];
|
||||||
|
}
|
||||||
|
if (((patchParam >> 4) & 4) != 0) {
|
||||||
|
cpt[12] = 2*cpt[8] - cpt[4];
|
||||||
|
cpt[13] = 2*cpt[9] - cpt[5];
|
||||||
|
cpt[14] = 2*cpt[10] - cpt[6];
|
||||||
|
cpt[15] = 2*cpt[11] - cpt[7];
|
||||||
|
}
|
||||||
|
if (((patchParam >> 4) & 8) != 0) {
|
||||||
|
cpt[0] = 2*cpt[1] - cpt[2];
|
||||||
|
cpt[4] = 2*cpt[5] - cpt[6];
|
||||||
|
cpt[8] = 2*cpt[9] - cpt[10];
|
||||||
|
cpt[12] = 2*cpt[13] - cpt[14];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compute single-crease patch matrix
|
// compute single-crease patch matrix
|
||||||
mat4
|
mat4
|
||||||
ComputeMatrixSimplified(float sharpness)
|
ComputeMatrixSimplified(float sharpness)
|
||||||
@ -117,44 +138,20 @@ void main()
|
|||||||
int i = ID%4;
|
int i = ID%4;
|
||||||
int j = ID/4;
|
int j = ID/4;
|
||||||
|
|
||||||
#if defined OSD_PATCH_BOUNDARY
|
vec3 position[24];
|
||||||
vec3 H[3];
|
for (int i=0; i<16; ++i) {
|
||||||
for (int l=0; l<3; ++l) {
|
position[i] = inpt[i].v.position.xyz;
|
||||||
H[l] = vec3(0,0,0);
|
|
||||||
for (int k=0; k<4; ++k) {
|
|
||||||
H[l] += Q[i][k] * inpt[l*4 + k].v.position.xyz;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 pos = vec3(0,0,0);
|
int patchParam = GetPatchParam();
|
||||||
for (int k=0; k<3; ++k) {
|
|
||||||
pos += B[j][k]*H[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
outpt[ID].v.position = vec4(pos, 1.0);
|
reflectBoundaryEdges(position, patchParam);
|
||||||
|
|
||||||
#elif defined OSD_PATCH_CORNER
|
|
||||||
vec3 H[3];
|
|
||||||
for (int l=0; l<3; ++l) {
|
|
||||||
H[l] = vec3(0,0,0);
|
|
||||||
for (int k=0; k<3; ++k) {
|
|
||||||
H[l] += B[3-i][2-k] * inpt[l*3 + k].v.position.xyz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 pos = vec3(0,0,0);
|
|
||||||
for (int k=0; k<3; ++k) {
|
|
||||||
pos += B[j][k]*H[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
outpt[ID].v.position = vec4(pos, 1.0);
|
|
||||||
|
|
||||||
#else // not OSD_PATCH_BOUNDARY, not OSD_PATCH_CORNER
|
|
||||||
vec3 H[4];
|
vec3 H[4];
|
||||||
for (int l=0; l<4; ++l) {
|
for (int l=0; l<4; ++l) {
|
||||||
H[l] = vec3(0,0,0);
|
H[l] = vec3(0,0,0);
|
||||||
for (int k=0; k<4; ++k) {
|
for (int k=0; k<4; ++k) {
|
||||||
H[l] += Q[i][k] * inpt[l*4 + k].v.position.xyz;
|
H[l] += Q[i][k] * position[l*4 + k].xyz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,28 +186,7 @@ void main()
|
|||||||
outpt[ID].v.position = vec4(pos, 1.0);
|
outpt[ID].v.position = vec4(pos, 1.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
OSD_USER_VARYING_PER_CONTROL_POINT(ID, ID);
|
||||||
|
|
||||||
|
|
||||||
#if defined OSD_PATCH_BOUNDARY
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 );
|
|
||||||
#elif defined OSD_PATCH_CORNER
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 2, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8 );
|
|
||||||
#else
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if OSD_TRANSITION_ROTATE == 0
|
|
||||||
const int r[16] = int[]( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 );
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 1
|
|
||||||
const int r[16] = int[]( 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3 );
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
|
||||||
const int r[16] = int[]( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 );
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
|
||||||
const int r[16] = int[]( 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OSD_USER_VARYING_PER_CONTROL_POINT(ID, p[r[ID]]);
|
|
||||||
|
|
||||||
int patchLevel = GetPatchLevel();
|
int patchLevel = GetPatchLevel();
|
||||||
|
|
||||||
@ -224,35 +200,17 @@ void main()
|
|||||||
if (ID == 0) {
|
if (ID == 0) {
|
||||||
OSD_PATCH_CULL(OSD_PATCH_INPUT_SIZE);
|
OSD_PATCH_CULL(OSD_PATCH_INPUT_SIZE);
|
||||||
|
|
||||||
#ifdef OSD_PATCH_TRANSITION
|
vec4 outerLevel = vec4(0);
|
||||||
vec3 cp[OSD_PATCH_INPUT_SIZE];
|
vec2 innerLevel = vec2(0);
|
||||||
for(int k = 0; k < OSD_PATCH_INPUT_SIZE; ++k) cp[k] = inpt[k].v.position.xyz;
|
GetTransitionTessLevels(position, patchParam, outerLevel, innerLevel);
|
||||||
SetTransitionTessLevels(cp, patchLevel);
|
|
||||||
#else
|
|
||||||
#if defined OSD_PATCH_BOUNDARY
|
|
||||||
const int p[4] = int[]( 1, 2, 5, 6 );
|
|
||||||
#elif defined OSD_PATCH_CORNER
|
|
||||||
const int p[4] = int[]( 1, 2, 4, 5 );
|
|
||||||
#else
|
|
||||||
const int p[4] = int[]( 5, 6, 9, 10 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
|
gl_TessLevelOuter[0] = outerLevel[0];
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(inpt[p[0]].v.position.xyz, inpt[p[2]].v.position.xyz);
|
gl_TessLevelOuter[1] = outerLevel[1];
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(inpt[p[0]].v.position.xyz, inpt[p[1]].v.position.xyz);
|
gl_TessLevelOuter[2] = outerLevel[2];
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(inpt[p[1]].v.position.xyz, inpt[p[3]].v.position.xyz);
|
gl_TessLevelOuter[3] = outerLevel[3];
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(inpt[p[2]].v.position.xyz, inpt[p[3]].v.position.xyz);
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
gl_TessLevelInner[0] = innerLevel[0];
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
gl_TessLevelInner[1] = innerLevel[1];
|
||||||
#else
|
|
||||||
gl_TessLevelInner[0] = GetTessLevel(patchLevel);
|
|
||||||
gl_TessLevelInner[1] = GetTessLevel(patchLevel);
|
|
||||||
gl_TessLevelOuter[0] = GetTessLevel(patchLevel);
|
|
||||||
gl_TessLevelOuter[1] = GetTessLevel(patchLevel);
|
|
||||||
gl_TessLevelOuter[2] = GetTessLevel(patchLevel);
|
|
||||||
gl_TessLevelOuter[3] = GetTessLevel(patchLevel);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,11 +227,13 @@ void main()
|
|||||||
layout(quads) in;
|
layout(quads) in;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* XXXdyu-patch-drawing support for frational spacing
|
||||||
#if defined OSD_FRACTIONAL_ODD_SPACING
|
#if defined OSD_FRACTIONAL_ODD_SPACING
|
||||||
layout(fractional_odd_spacing) in;
|
layout(fractional_odd_spacing) in;
|
||||||
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
||||||
layout(fractional_even_spacing) in;
|
layout(fractional_even_spacing) in;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
in block {
|
in block {
|
||||||
ControlVertex v;
|
ControlVertex v;
|
||||||
@ -292,11 +252,7 @@ out block {
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
#ifdef OSD_PATCH_TRANSITION
|
vec2 UV = GetTransitionParameterization();
|
||||||
vec2 UV = GetTransitionSubpatchUV();
|
|
||||||
#else
|
|
||||||
vec2 UV = gl_TessCoord.xy;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||||
float B[4], D[4], C[4];
|
float B[4], D[4], C[4];
|
||||||
@ -340,15 +296,7 @@ void main()
|
|||||||
inpt[k].P2.xyz);
|
inpt[k].P2.xyz);
|
||||||
|
|
||||||
#else // !SINGLE_CREASE
|
#else // !SINGLE_CREASE
|
||||||
#if OSD_TRANSITION_ROTATE == 1
|
|
||||||
vec3 A = inpt[4*(3-j) + i].v.position.xyz;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
|
||||||
vec3 A = inpt[4*(3-i) + (3-j)].v.position.xyz;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
|
||||||
vec3 A = inpt[4*j + (3-i)].v.position.xyz;
|
|
||||||
#else // OSD_TRANSITION_ROTATE == 0, or non-transition patch
|
|
||||||
vec3 A = inpt[4*i + j].v.position.xyz;
|
vec3 A = inpt[4*i + j].v.position.xyz;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
BUCP[i] += A * B[j];
|
BUCP[i] += A * B[j];
|
||||||
DUCP[i] += A * D[j];
|
DUCP[i] += A * D[j];
|
||||||
@ -403,7 +351,10 @@ void main()
|
|||||||
Nu = Nu/length(n) - n * (dot(Nu,n)/pow(dot(n,n), 1.5));
|
Nu = Nu/length(n) - n * (dot(Nu,n)/pow(dot(n,n), 1.5));
|
||||||
Nv = Nv/length(n) - n * (dot(Nv,n)/pow(dot(n,n), 1.5));
|
Nv = Nv/length(n) - n * (dot(Nv,n)/pow(dot(n,n), 1.5));
|
||||||
|
|
||||||
OSD_COMPUTE_PTEX_COMPATIBLE_DERIVATIVES(OSD_TRANSITION_ROTATE);
|
outpt.v.tangent = Tangent;
|
||||||
|
outpt.v.bitangent = BiTangent;
|
||||||
|
outpt.v.Nu = Nu;
|
||||||
|
outpt.v.Nv = Nv;
|
||||||
#else
|
#else
|
||||||
Univar4x4(UV.y, B, D);
|
Univar4x4(UV.y, B, D);
|
||||||
|
|
||||||
@ -418,7 +369,8 @@ void main()
|
|||||||
|
|
||||||
vec3 normal = normalize(cross(Tangent, BiTangent));
|
vec3 normal = normalize(cross(Tangent, BiTangent));
|
||||||
|
|
||||||
OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(OSD_TRANSITION_ROTATE);
|
outpt.v.tangent = Tangent;
|
||||||
|
outpt.v.bitangent = BiTangent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
outpt.v.position = vec4(WorldPos, 1.0f);
|
outpt.v.position = vec4(WorldPos, 1.0f);
|
||||||
@ -428,15 +380,7 @@ void main()
|
|||||||
|
|
||||||
outpt.v.patchCoord = inpt[0].v.patchCoord;
|
outpt.v.patchCoord = inpt[0].v.patchCoord;
|
||||||
|
|
||||||
#if OSD_TRANSITION_ROTATE == 1
|
|
||||||
outpt.v.patchCoord.xy = vec2(UV.y, 1.0-UV.x);
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
|
||||||
outpt.v.patchCoord.xy = vec2(1.0-UV.x, 1.0-UV.y);
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
|
||||||
outpt.v.patchCoord.xy = vec2(1.0-UV.y, UV.x);
|
|
||||||
#else // OSD_TRANNSITION_ROTATE == 0, or non-transition patch
|
|
||||||
outpt.v.patchCoord.xy = vec2(UV.x, UV.y);
|
outpt.v.patchCoord.xy = vec2(UV.x, UV.y);
|
||||||
#endif
|
|
||||||
|
|
||||||
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
|
OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER;
|
||||||
|
|
||||||
|
@ -183,10 +183,13 @@ float TessAdaptive(vec3 p0, vec3 p1)
|
|||||||
|
|
||||||
uniform isamplerBuffer OsdPatchParamBuffer;
|
uniform isamplerBuffer OsdPatchParamBuffer;
|
||||||
|
|
||||||
|
#define GetPatchParam() \
|
||||||
|
(texelFetch(OsdPatchParamBuffer, GetPrimitiveID()).y)
|
||||||
|
|
||||||
#define GetPatchLevel() \
|
#define GetPatchLevel() \
|
||||||
(texelFetch(OsdPatchParamBuffer, GetPrimitiveID()).y & 0xf)
|
(texelFetch(OsdPatchParamBuffer, GetPrimitiveID()).y & 0xf)
|
||||||
|
|
||||||
#define GetSharpness() \
|
#define GetSharpness() \
|
||||||
(intBitsToFloat(texelFetch(OsdPatchParamBuffer, GetPrimitiveID()).z))
|
(intBitsToFloat(texelFetch(OsdPatchParamBuffer, GetPrimitiveID()).z))
|
||||||
|
|
||||||
#define OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER \
|
#define OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER \
|
||||||
@ -194,12 +197,11 @@ uniform isamplerBuffer OsdPatchParamBuffer;
|
|||||||
ivec2 ptexIndex = texelFetch(OsdPatchParamBuffer, \
|
ivec2 ptexIndex = texelFetch(OsdPatchParamBuffer, \
|
||||||
GetPrimitiveID()).xy; \
|
GetPrimitiveID()).xy; \
|
||||||
int faceID = ptexIndex.x; \
|
int faceID = ptexIndex.x; \
|
||||||
int lv = 1 << ((ptexIndex.y & 0xf) - ((ptexIndex.y >> 4) & 1)); \
|
int lv = 1 << ((ptexIndex.y & 0x7) - ((ptexIndex.y >> 3) & 1)); \
|
||||||
int u = (ptexIndex.y >> 17) & 0x3ff; \
|
int u = (ptexIndex.y >> 22) & 0x3ff; \
|
||||||
int v = (ptexIndex.y >> 7) & 0x3ff; \
|
int v = (ptexIndex.y >> 12) & 0x3ff; \
|
||||||
int rotation = (ptexIndex.y >> 5) & 0x3; \
|
|
||||||
outpt[ID].v.patchCoord.w = faceID+0.5; \
|
outpt[ID].v.patchCoord.w = faceID+0.5; \
|
||||||
outpt[ID].v.ptexInfo = ivec4(u, v, lv, rotation); \
|
outpt[ID].v.ptexInfo = ivec4(u, v, lv, 0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER \
|
#define OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER \
|
||||||
@ -207,57 +209,8 @@ uniform isamplerBuffer OsdPatchParamBuffer;
|
|||||||
vec2 uv = outpt.v.patchCoord.xy; \
|
vec2 uv = outpt.v.patchCoord.xy; \
|
||||||
ivec2 p = inpt[0].v.ptexInfo.xy; \
|
ivec2 p = inpt[0].v.ptexInfo.xy; \
|
||||||
int lv = inpt[0].v.ptexInfo.z; \
|
int lv = inpt[0].v.ptexInfo.z; \
|
||||||
int rot = inpt[0].v.ptexInfo.w; \
|
|
||||||
outpt.v.tessCoord.xy = uv; \
|
outpt.v.tessCoord.xy = uv; \
|
||||||
uv.xy = float(rot==0)*uv.xy \
|
outpt.v.patchCoord.xy = (uv * vec2(1.0)/lv) + vec2(p.x, p.y)/lv;\
|
||||||
+ float(rot==1)*vec2(1.0-uv.y, uv.x) \
|
|
||||||
+ float(rot==2)*vec2(1.0-uv.x, 1.0-uv.y) \
|
|
||||||
+ float(rot==3)*vec2(uv.y, 1.0-uv.x); \
|
|
||||||
outpt.v.patchCoord.xy = (uv * vec2(1.0)/lv) + vec2(p.x, p.y)/lv; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(ROTATE) \
|
|
||||||
{ \
|
|
||||||
int rot = (inpt[0].v.ptexInfo.w + 4 - ROTATE)%4; \
|
|
||||||
if (rot == 1) { \
|
|
||||||
outpt.v.tangent = -BiTangent; \
|
|
||||||
outpt.v.bitangent = Tangent; \
|
|
||||||
} else if (rot == 2) { \
|
|
||||||
outpt.v.tangent = -Tangent; \
|
|
||||||
outpt.v.bitangent = -BiTangent; \
|
|
||||||
} else if (rot == 3) { \
|
|
||||||
outpt.v.tangent = BiTangent; \
|
|
||||||
outpt.v.bitangent = -Tangent; \
|
|
||||||
} else { \
|
|
||||||
outpt.v.tangent = Tangent; \
|
|
||||||
outpt.v.bitangent = BiTangent; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OSD_COMPUTE_PTEX_COMPATIBLE_DERIVATIVES(ROTATE) \
|
|
||||||
{ \
|
|
||||||
int rot = (inpt[0].v.ptexInfo.w + 4 - ROTATE)%4; \
|
|
||||||
if (rot == 1) { \
|
|
||||||
outpt.v.tangent = -BiTangent; \
|
|
||||||
outpt.v.bitangent = Tangent; \
|
|
||||||
outpt.v.Nu = -Nv; \
|
|
||||||
outpt.v.Nv = Nv; \
|
|
||||||
} else if (rot == 2) { \
|
|
||||||
outpt.v.tangent = -Tangent; \
|
|
||||||
outpt.v.bitangent = -BiTangent; \
|
|
||||||
outpt.v.Nu = -Nu; \
|
|
||||||
outpt.v.Nv = -Nv; \
|
|
||||||
} else if (rot == 3) { \
|
|
||||||
outpt.v.tangent = BiTangent; \
|
|
||||||
outpt.v.bitangent = -Tangent; \
|
|
||||||
outpt.v.Nu = Nv; \
|
|
||||||
outpt.v.Nv = -Nu; \
|
|
||||||
} else { \
|
|
||||||
outpt.v.tangent = Tangent; \
|
|
||||||
outpt.v.bitangent = BiTangent; \
|
|
||||||
outpt.v.Nu = Nu; \
|
|
||||||
outpt.v.Nv = Nv; \
|
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -441,11 +441,13 @@ void main()
|
|||||||
layout(quads) in;
|
layout(quads) in;
|
||||||
layout(cw) in;
|
layout(cw) in;
|
||||||
|
|
||||||
|
/* XXXdyu-patch-drawing support for frational spacing
|
||||||
#if defined OSD_FRACTIONAL_ODD_SPACING
|
#if defined OSD_FRACTIONAL_ODD_SPACING
|
||||||
layout(fractional_odd_spacing) in;
|
layout(fractional_odd_spacing) in;
|
||||||
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
||||||
layout(fractional_even_spacing) in;
|
layout(fractional_even_spacing) in;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
in block {
|
in block {
|
||||||
GregEvalVertex v;
|
GregEvalVertex v;
|
||||||
|
@ -119,11 +119,13 @@ void main()
|
|||||||
layout(quads) in;
|
layout(quads) in;
|
||||||
layout(cw) in;
|
layout(cw) in;
|
||||||
|
|
||||||
|
/* XXXdyu-patch-drawing support for frational spacing
|
||||||
#if defined OSD_FRACTIONAL_ODD_SPACING
|
#if defined OSD_FRACTIONAL_ODD_SPACING
|
||||||
layout(fractional_odd_spacing) in;
|
layout(fractional_odd_spacing) in;
|
||||||
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
||||||
layout(fractional_even_spacing) in;
|
layout(fractional_even_spacing) in;
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
in block {
|
in block {
|
||||||
ControlVertex v;
|
ControlVertex v;
|
||||||
|
@ -22,431 +22,85 @@
|
|||||||
// language governing permissions and limitations under the Apache License.
|
// language governing permissions and limitations under the Apache License.
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined(OSD_TRANSITION_PATTERN00) || defined(OSD_TRANSITION_PATTERN01) || defined(OSD_TRANSITION_PATTERN02) || defined(OSD_TRANSITION_PATTERN10) || defined(OSD_TRANSITION_PATTERN11) || defined(OSD_TRANSITION_PATTERN12) || defined(OSD_TRANSITION_PATTERN13) || defined(OSD_TRANSITION_PATTERN21) || defined(OSD_TRANSITION_PATTERN22) || defined(OSD_TRANSITION_PATTERN23)
|
|
||||||
|
|
||||||
#define OSD_TRANSITION_TRIANGLE_SUBPATCH
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#undef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
// Patches.TessControlTransition
|
// Patches.TessControlTransition
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
#ifdef OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER
|
#ifdef OSD_PATCH_TESS_CONTROL_BSPLINE_SHADER
|
||||||
|
|
||||||
void
|
patch out vec4 tessOuterLo, tessOuterHi;
|
||||||
SetTransitionTessLevels(vec3 cp[OSD_PATCH_INPUT_SIZE], int patchLevel)
|
|
||||||
|
float
|
||||||
|
TessAdaptiveRound(vec3 p0, vec3 p1)
|
||||||
{
|
{
|
||||||
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
|
return round(TessAdaptive(p0, p1));
|
||||||
// These tables map the 9, 12, or 16 input control points onto the
|
}
|
||||||
// canonical 16 control points for a regular patch.
|
|
||||||
#if defined OSD_PATCH_BOUNDARY
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 );
|
|
||||||
#elif defined OSD_PATCH_CORNER
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 2, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8 );
|
|
||||||
#else
|
|
||||||
const int p[16] = int[]( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if OSD_TRANSITION_ROTATE == 0
|
void
|
||||||
const int r[16] = int[]( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 );
|
GetTransitionTessLevels(vec3 cp[24], int patchParam, inout vec4 outer, inout vec2 inner)
|
||||||
#elif OSD_TRANSITION_ROTATE == 1
|
{
|
||||||
const int r[16] = int[]( 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3 );
|
// Each edge of a transition patch is adjacent to one or two patches
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
// at the next refined level of subdivision. We compute the corresponding
|
||||||
const int r[16] = int[]( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 );
|
// vertex-vertex and edge-vertex refined points along the edges of the
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
// patch using Catmull-Clark subdivision stencil weights.
|
||||||
const int r[16] = int[]( 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Expand and rotate control points using remapping tables above
|
|
||||||
vec3 pv0 = cp[p[r[0]]];
|
|
||||||
vec3 pv1 = cp[p[r[1]]];
|
|
||||||
vec3 pv2 = cp[p[r[2]]];
|
|
||||||
vec3 pv3 = cp[p[r[3]]];
|
|
||||||
|
|
||||||
vec3 pv4 = cp[p[r[4]]];
|
|
||||||
vec3 pv5 = cp[p[r[5]]];
|
|
||||||
vec3 pv6 = cp[p[r[6]]];
|
|
||||||
vec3 pv7 = cp[p[r[7]]];
|
|
||||||
|
|
||||||
vec3 pv8 = cp[p[r[8]]];
|
|
||||||
vec3 pv9 = cp[p[r[9]]];
|
|
||||||
vec3 pv10 = cp[p[r[10]]];
|
|
||||||
vec3 pv11 = cp[p[r[11]]];
|
|
||||||
|
|
||||||
vec3 pv12 = cp[p[r[12]]];
|
|
||||||
vec3 pv13 = cp[p[r[13]]];
|
|
||||||
vec3 pv14 = cp[p[r[14]]];
|
|
||||||
vec3 pv15 = cp[p[r[15]]];
|
|
||||||
|
|
||||||
// Each edge of a transition patch is adjacent to one or two
|
|
||||||
// patches at the next refined level of subdivision.
|
|
||||||
// Compute the corresponding vertex-vertex and edge-vertex refined
|
|
||||||
// points along the edges of the patch using Catmull-Clark subdivision
|
|
||||||
// stencil weights.
|
|
||||||
// For simplicity, we let the optimizer discard unused computation.
|
// For simplicity, we let the optimizer discard unused computation.
|
||||||
vec3 vv0 = (pv0 + pv2 + pv8 + pv10) * 0.015625 +
|
cp[16] = (cp[0] + cp[2] + cp[8] + cp[10]) * 0.015625 +
|
||||||
(pv1 + pv4 + pv6 + pv9) * 0.09375 + pv5 * 0.5625;
|
(cp[1] + cp[4] + cp[6] + cp[9]) * 0.09375 + cp[5] * 0.5625;
|
||||||
vec3 ev01 = (pv1 + pv2 + pv9 + pv10) * 0.0625 + (pv5 + pv6) * 0.375;
|
cp[17] = (cp[1] + cp[2] + cp[9] + cp[10]) * 0.0625 + (cp[5] + cp[6]) * 0.375;
|
||||||
|
|
||||||
vec3 vv1 = (pv1 + pv3 + pv9 + pv11) * 0.015625 +
|
cp[18] = (cp[1] + cp[3] + cp[9] + cp[11]) * 0.015625 +
|
||||||
(pv2 + pv5 + pv7 + pv10) * 0.09375 + pv6 * 0.5625;
|
(cp[2] + cp[5] + cp[7] + cp[10]) * 0.09375 + cp[6] * 0.5625;
|
||||||
vec3 ev12 = (pv5 + pv7 + pv9 + pv11) * 0.0625 + (pv6 + pv10) * 0.375;
|
cp[19] = (cp[5] + cp[7] + cp[9] + cp[11]) * 0.0625 + (cp[6] + cp[10]) * 0.375;
|
||||||
|
|
||||||
vec3 vv2 = (pv5 + pv7 + pv13 + pv15) * 0.015625 +
|
cp[20] = (cp[5] + cp[7] + cp[13] + cp[15]) * 0.015625 +
|
||||||
(pv6 + pv9 + pv11 + pv14) * 0.09375 + pv10 * 0.5625;
|
(cp[6] + cp[9] + cp[11] + cp[14]) * 0.09375 + cp[10] * 0.5625;
|
||||||
vec3 ev23 = (pv5 + pv6 + pv13 + pv14) * 0.0625 + (pv9 + pv10) * 0.375;
|
cp[21] = (cp[5] + cp[6] + cp[13] + cp[14]) * 0.0625 + (cp[9] + cp[10]) * 0.375;
|
||||||
|
|
||||||
vec3 vv3 = (pv4 + pv6 + pv12 + pv14) * 0.015625 +
|
cp[22] = (cp[4] + cp[6] + cp[12] + cp[14]) * 0.015625 +
|
||||||
(pv5 + pv8 + pv10 + pv13) * 0.09375 + pv9 * 0.5625;
|
(cp[5] + cp[8] + cp[10] + cp[13]) * 0.09375 + cp[9] * 0.5625;
|
||||||
vec3 ev30 = (pv4 + pv6 + pv8 + pv10) * 0.0625 + (pv5 + pv9) * 0.375;
|
cp[23] = (cp[4] + cp[6] + cp[8] + cp[10]) * 0.0625 + (cp[5] + cp[9]) * 0.375;
|
||||||
|
|
||||||
// The vertices along boundaries and at corners are refined specially.
|
tessOuterLo = vec4(1);
|
||||||
#if defined OSD_PATCH_BOUNDARY
|
tessOuterHi = vec4(0);
|
||||||
#if OSD_TRANSITION_ROTATE == 0
|
|
||||||
vv0 = (pv4 + pv6) * 0.125 + pv5 * 0.75;
|
|
||||||
vv1 = (pv5 + pv7) * 0.125 + pv6 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 1
|
|
||||||
vv1 = (pv2 + pv10) * 0.125 + pv6 * 0.75;
|
|
||||||
vv2 = (pv6 + pv14) * 0.125 + pv10 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
|
||||||
vv2 = (pv9 + pv11) * 0.125 + pv10 * 0.75;
|
|
||||||
vv3 = (pv8 + pv10) * 0.125 + pv9 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
|
||||||
vv3 = (pv5 + pv13) * 0.125 + pv9 * 0.75;
|
|
||||||
vv0 = (pv1 + pv9) * 0.125 + pv5 * 0.75;
|
|
||||||
#endif
|
|
||||||
#elif defined OSD_PATCH_CORNER
|
|
||||||
#if OSD_TRANSITION_ROTATE == 0
|
|
||||||
vv0 = (pv4 + pv6) * 0.125 + pv5 * 0.75;
|
|
||||||
vv1 = pv6;
|
|
||||||
vv2 = (pv6 + pv14) * 0.125 + pv10 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 1
|
|
||||||
vv1 = (pv2 + pv10) * 0.125 + pv6 * 0.75;
|
|
||||||
vv2 = pv10;
|
|
||||||
vv3 = (pv8 + pv10) * 0.125 + pv9 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 2
|
|
||||||
vv2 = (pv9 + pv11) * 0.125 + pv10 * 0.75;
|
|
||||||
vv3 = pv9;
|
|
||||||
vv0 = (pv1 + pv9) * 0.125 + pv5 * 0.75;
|
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
|
||||||
vv3 = (pv5 + pv13) * 0.125 + pv9 * 0.75;
|
|
||||||
vv0 = pv5;
|
|
||||||
vv1 = (pv5 + pv7) * 0.125 + pv6 * 0.75;
|
|
||||||
#endif
|
|
||||||
#elif defined OSD_PATCH_SINGLE_CREASE
|
|
||||||
// apply smooth, sharp or fractional-semisharp (linear interpolate) rules
|
|
||||||
float weight = min(1, GetSharpness());
|
|
||||||
|
|
||||||
// XXX: current rotation of single-crease patch is inconsistent
|
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||||
// to boundary patch. should be fixed.
|
float tessAmount = GetTessLevel(GetPatchLevel());
|
||||||
#if OSD_TRANSITION_ROTATE == 2
|
|
||||||
vv0 = mix(vv0, (pv4 + pv6) * 0.125 + pv5 * 0.75, weight);
|
if (((patchParam >> 11) & 1) != 0) {
|
||||||
vv1 = mix(vv1, (pv5 + pv7) * 0.125 + pv6 * 0.75, weight);
|
tessOuterLo[0] = TessAdaptiveRound(cp[23], cp[16]);
|
||||||
#elif OSD_TRANSITION_ROTATE == 3
|
tessOuterHi[0] = TessAdaptiveRound(cp[22], cp[23]);
|
||||||
vv1 = mix(vv1, (pv2 + pv10) * 0.125 + pv6 * 0.75, weight);
|
} else {
|
||||||
vv2 = mix(vv2, (pv6 + pv14) * 0.125 + pv10 * 0.75, weight);
|
tessOuterLo[0] = TessAdaptiveRound(cp[5], cp[9]);
|
||||||
#elif OSD_TRANSITION_ROTATE == 0
|
}
|
||||||
vv2 = mix(vv2, (pv9 + pv11) * 0.125 + pv10 * 0.75, weight);
|
if (((patchParam >> 8) & 1) != 0) {
|
||||||
vv3 = mix(vv3, (pv8 + pv10) * 0.125 + pv9 * 0.75, weight);
|
tessOuterLo[1] = TessAdaptiveRound(cp[16], cp[17]);
|
||||||
#elif OSD_TRANSITION_ROTATE == 1
|
tessOuterHi[1] = TessAdaptiveRound(cp[17], cp[18]);
|
||||||
vv3 = mix(vv3, (pv5 + pv13) * 0.125 + pv9 * 0.75, weight);
|
} else {
|
||||||
vv0 = mix(vv0, (pv1 + pv9) * 0.125 + pv5 * 0.75, weight);
|
tessOuterLo[1] = TessAdaptiveRound(cp[5], cp[6]);
|
||||||
|
}
|
||||||
|
if (((patchParam >> 9) & 1) != 0) {
|
||||||
|
tessOuterLo[2] = TessAdaptiveRound(cp[18], cp[19]);
|
||||||
|
tessOuterHi[2] = TessAdaptiveRound(cp[19], cp[20]);
|
||||||
|
} else {
|
||||||
|
tessOuterLo[2] = TessAdaptiveRound(cp[6], cp[10]);
|
||||||
|
}
|
||||||
|
if (((patchParam >> 10) & 1) != 0) {
|
||||||
|
tessOuterLo[3] = TessAdaptiveRound(cp[21], cp[22]);
|
||||||
|
tessOuterHi[3] = TessAdaptiveRound(cp[20], cp[21]);
|
||||||
|
} else {
|
||||||
|
tessOuterLo[3] = TessAdaptiveRound(cp[9], cp[10]);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
float tessAmount = GetTessLevel(GetPatchLevel());
|
||||||
|
|
||||||
|
tessOuterLo[0] = tessAmount;
|
||||||
|
tessOuterLo[1] = tessAmount;
|
||||||
|
tessOuterLo[2] = tessAmount;
|
||||||
|
tessOuterLo[3] = tessAmount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
outer = tessOuterLo + tessOuterHi;
|
||||||
|
inner[0] = (outer[0] + outer[2]) * 0.5;
|
||||||
|
inner[1] = (outer[1] + outer[3]) * 0.5;
|
||||||
#ifdef OSD_TRANSITION_PATTERN00
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, pv9) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, pv10) * 0.5;
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(pv9, pv10);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.5;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN01
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, vv1);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(pv6, pv10);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev01, pv10) * 0.5;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.25;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN02
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, vv0);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, pv9) * 0.5;
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(pv5, pv9);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.25;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN10
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(pv6, pv10);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, pv10);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev01, vv1);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[1]) * 0.25;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN11
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(pv9, pv10);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev30, vv3);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev30, pv10);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[2]) * 0.25;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN12
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev30, vv0);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, vv0);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev01, ev30);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.25;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN13
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, pv10);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev30, pv10);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev01, ev30);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.25;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN20
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(pv5, pv6);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev12, vv1);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev12, ev30);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev30, vv0);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN21
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev23, ev30) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev23, vv3);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev30, vv3);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = (gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.5;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN22
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev12, vv2);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev23, vv2);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev12, ev23) * 0.5;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = (gl_TessLevelOuter[0] + gl_TessLevelOuter[1]) * 0.5;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN23
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev12, ev30);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev12, ev23) * 0.5;
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev23, ev30) * 0.5;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] =
|
|
||||||
(gl_TessLevelOuter[0] + gl_TessLevelOuter[1] + gl_TessLevelOuter[2]) * 0.5;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN30
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev30, ev12) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev30, vv0);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev01, vv0);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev01, ev23) * 0.5;
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN31
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, ev23) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev23, vv3);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev30, vv3);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev30, ev12) * 0.5;
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN32
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev23, ev01) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, vv1);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev12, vv1);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev12, ev30) * 0.5;
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN33
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev12, ev30) * 0.5;
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev12, vv2);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev23, vv2);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev01, ev23) * 0.5;
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN40
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, vv0);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(ev01, ev23);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev23, vv3);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(pv5, pv9);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN41
|
|
||||||
gl_TessLevelOuter[0] = TessAdaptive(ev01, vv1);
|
|
||||||
gl_TessLevelOuter[1] = TessAdaptive(pv6, pv10);
|
|
||||||
gl_TessLevelOuter[2] = TessAdaptive(ev23, vv2);
|
|
||||||
gl_TessLevelOuter[3] = TessAdaptive(ev01, ev23);
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = max(gl_TessLevelOuter[1], gl_TessLevelOuter[3]);
|
|
||||||
gl_TessLevelInner[1] = max(gl_TessLevelOuter[0], gl_TessLevelOuter[2]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // OSD_ENABLE_SCREENSPACE_TESSELLATION
|
|
||||||
|
|
||||||
float TessAmount = GetTessLevel(patchLevel);
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN00
|
|
||||||
float side = sqrt(1.25)*TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = side;
|
|
||||||
gl_TessLevelOuter[1] = side;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN01
|
|
||||||
float side = sqrt(1.25)*TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount;
|
|
||||||
gl_TessLevelOuter[2] = side;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN02
|
|
||||||
float side = sqrt(1.25)*TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = side;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN10
|
|
||||||
float side = sqrt(1.25) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount;
|
|
||||||
gl_TessLevelOuter[1] = side;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount/2.0;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN11
|
|
||||||
float side = sqrt(1.25) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[2] = side;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN12
|
|
||||||
float side = sqrt(0.125) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[2] = side;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN13
|
|
||||||
float side1 = sqrt(1.25) * TessAmount;
|
|
||||||
float side2 = sqrt(0.125) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = side1;
|
|
||||||
gl_TessLevelOuter[1] = side1;
|
|
||||||
gl_TessLevelOuter[2] = side2;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0*1.414;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN20
|
|
||||||
gl_TessLevelOuter[0] = TessAmount;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount;
|
|
||||||
gl_TessLevelOuter[3] = TessAmount/2.0;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelInner[1] = TessAmount;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN21
|
|
||||||
float side = sqrt(0.125) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = side;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount/2.0;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN22
|
|
||||||
float side = sqrt(0.125) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[2] = side;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN23
|
|
||||||
float side = sqrt(0.125) * TessAmount;
|
|
||||||
gl_TessLevelOuter[0] = TessAmount;
|
|
||||||
gl_TessLevelOuter[1] = side;
|
|
||||||
gl_TessLevelOuter[2] = side;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN30
|
|
||||||
gl_TessLevelOuter[0] = gl_TessLevelOuter[1] =
|
|
||||||
gl_TessLevelOuter[2] = gl_TessLevelOuter[3] = TessAmount/2.0;
|
|
||||||
gl_TessLevelInner[0] = gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN31
|
|
||||||
gl_TessLevelOuter[0] = gl_TessLevelOuter[1] =
|
|
||||||
gl_TessLevelOuter[2] = gl_TessLevelOuter[3] = TessAmount/2.0;
|
|
||||||
gl_TessLevelInner[0] = gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN32
|
|
||||||
gl_TessLevelOuter[0] = gl_TessLevelOuter[1] =
|
|
||||||
gl_TessLevelOuter[2] = gl_TessLevelOuter[3] = TessAmount/2.0;
|
|
||||||
gl_TessLevelInner[0] = gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN33
|
|
||||||
gl_TessLevelOuter[0] = gl_TessLevelOuter[1] =
|
|
||||||
gl_TessLevelOuter[2] = gl_TessLevelOuter[3] = TessAmount/2.0;
|
|
||||||
gl_TessLevelInner[0] = gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN40
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[3] = TessAmount;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount;
|
|
||||||
gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN41
|
|
||||||
gl_TessLevelOuter[0] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[1] = TessAmount;
|
|
||||||
gl_TessLevelOuter[2] = TessAmount/2.0;
|
|
||||||
gl_TessLevelOuter[3] = TessAmount;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = TessAmount;
|
|
||||||
gl_TessLevelInner[1] = TessAmount/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // OSD_ENABLE_SCREENSPACE_TESSELLATION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -456,142 +110,37 @@ SetTransitionTessLevels(vec3 cp[OSD_PATCH_INPUT_SIZE], int patchLevel)
|
|||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
#ifdef OSD_PATCH_TESS_EVAL_BSPLINE_SHADER
|
#ifdef OSD_PATCH_TESS_EVAL_BSPLINE_SHADER
|
||||||
|
|
||||||
vec2
|
patch in vec4 tessOuterLo, tessOuterHi;
|
||||||
GetTransitionSubpatchUV()
|
|
||||||
|
float
|
||||||
|
GetTransitionSplit(float t, float n0, float n1)
|
||||||
{
|
{
|
||||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
float n = round(n0 + n1);
|
||||||
vec3 uvw = gl_TessCoord.xyz;
|
float ti = round(t * n);
|
||||||
#else
|
|
||||||
vec2 uv = gl_TessCoord.xy;
|
|
||||||
#endif
|
|
||||||
vec2 UV = vec2(0, 0);
|
|
||||||
|
|
||||||
// OSD_TRANSITION_PATTERN0*
|
if (ti <= n0) {
|
||||||
// +-------------+
|
return 0.5 * (ti / n0);
|
||||||
// | /\\ |
|
} else {
|
||||||
// | 1 / \\ 2 |
|
return 0.5 * ((ti - n0) / n1) + 0.5;
|
||||||
// | / \\ |
|
}
|
||||||
// | / \\ |
|
}
|
||||||
// | / 0 \\ |
|
|
||||||
// |/ \\|
|
|
||||||
// +-------------+
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN00
|
|
||||||
UV.x = 1.0-uvw.y-uvw.z/2;
|
|
||||||
UV.y = 1.0-uvw.z;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN01
|
|
||||||
UV.x = 1.0-uvw.y/2;
|
|
||||||
UV.y = uvw.x;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN02
|
|
||||||
UV.x = uvw.z/2;
|
|
||||||
UV.y = uvw.x;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OSD_TRANSITION_PATTERN1*
|
|
||||||
// +-------------+
|
|
||||||
// | 0 /\\ 2 |
|
|
||||||
// | / \\ |
|
|
||||||
// | / 3 \\ |
|
|
||||||
// | / / |
|
|
||||||
// | / / 1 |
|
|
||||||
// |/ / |
|
|
||||||
// +-------------+
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN10
|
|
||||||
UV.x = 1.0-uvw.x/2.0;
|
|
||||||
UV.y = uvw.z;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN11
|
|
||||||
UV.x = uvw.y;
|
|
||||||
UV.y = 1.0-uvw.x/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN12
|
|
||||||
UV.x = uvw.x/2.0;
|
|
||||||
UV.y = uvw.y/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN13
|
|
||||||
UV.x = 1.0-uvw.x-uvw.y/2.0;
|
|
||||||
UV.y = 1.0-uvw.y-uvw.x/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OSD_TRANSITION_PATTERN2*
|
|
||||||
// +-------------+
|
|
||||||
// | |
|
|
||||||
// | 0 |
|
|
||||||
// | |
|
|
||||||
// |-------------|
|
|
||||||
// |\\ 3 / |
|
|
||||||
// | \\ / |
|
|
||||||
// | 1 \\ / 2 |
|
|
||||||
// +-------------+
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN20
|
|
||||||
UV.x = 1.0-uv.y;
|
|
||||||
UV.y = uv.x/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN21
|
|
||||||
UV.x = uvw.z/2.0;
|
|
||||||
UV.y = 1.0-uvw.y/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN22
|
|
||||||
UV.x = 1.0-uvw.x/2.0;
|
|
||||||
UV.y = 1.0-uvw.y/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN23
|
|
||||||
UV.x = 1.0-uvw.y-uvw.x/2;
|
|
||||||
UV.y = 0.5+uvw.x/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OSD_TRANSITION_PATTERN3*
|
|
||||||
// +-------------+
|
|
||||||
// | | |
|
|
||||||
// | 1 | 0 |
|
|
||||||
// | | |
|
|
||||||
// |------|------|
|
|
||||||
// | | |
|
|
||||||
// | 3 | 2 |
|
|
||||||
// | | |
|
|
||||||
// +-------------+
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN30
|
|
||||||
UV.x = uv.y/2.0;
|
|
||||||
UV.y = 0.5 - uv.x/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN31
|
|
||||||
UV.x = 0.5 - uv.x/2.0;
|
|
||||||
UV.y = 1.0 - uv.y/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN32
|
|
||||||
UV.x = 0.5 + uv.x/2.0;
|
|
||||||
UV.y = uv.y/2.0;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN33
|
|
||||||
UV.x = 1.0 - uv.y/2.0;
|
|
||||||
UV.y = 0.5 + uv.x/2.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OSD_TRANSITION_PATTERN4*
|
|
||||||
// +-------------+
|
|
||||||
// | | |
|
|
||||||
// | | |
|
|
||||||
// | | |
|
|
||||||
// | 1 | 0 |
|
|
||||||
// | | |
|
|
||||||
// | | |
|
|
||||||
// | | |
|
|
||||||
// +-------------+
|
|
||||||
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN40
|
|
||||||
UV.x = 0.5 - uv.y/2.0;
|
|
||||||
UV.y = uv.x;
|
|
||||||
#endif
|
|
||||||
#ifdef OSD_TRANSITION_PATTERN41
|
|
||||||
UV.x = 1.0 - uv.y/2.0;
|
|
||||||
UV.y = uv.x;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
vec2
|
||||||
|
GetTransitionParameterization()
|
||||||
|
{
|
||||||
|
vec2 UV = gl_TessCoord.xy;
|
||||||
|
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||||
|
UV.y = GetTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||||
|
} else
|
||||||
|
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||||
|
UV.x = GetTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||||
|
} else
|
||||||
|
if (UV.x == 1 && tessOuterHi[2] > 0) {
|
||||||
|
UV.y = GetTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
||||||
|
} else
|
||||||
|
if (UV.y == 1 && tessOuterHi[3] > 0) {
|
||||||
|
UV.x = GetTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
||||||
|
}
|
||||||
return UV;
|
return UV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user