Hi cronicryo,
Sorry for the late reply, and I think I made some mistakes earlier.
I tried to modify the vp2BlinnShader along with fileTexture in our devkit. It can use a texture from file now. There is still a problem with swatch display, I'll simply remove it for now.
To make vp2BlinnShader display a texture from a file.
I created a shader fragment as I mentioned before, but the diffuseColor should be float4 instead of float3. And the diffuseColor property should be diffuseColor instead of color.
void initializeFragmentShaders()
{
static const MString sFragmentName("fileTexturePluginFragment");
static const char* sFragmentBody =
"<fragment uiName=\"fileTexturePluginFragment\" name=\"fileTexturePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
" <description><![CDATA[Simple file texture fragment]]></description>"
" <properties>"
" <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
" <texture2 name=\"map\" />"
" <sampler name=\"textureSampler\" />"
" </properties>"
" <values>"
" </values>"
" <outputs>"
" <float4 name=\"output\" />"
" </outputs>"
" <implementation>"
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.100000\">"
" <function_name val=\"fileTexturePluginFragment\" />"
" <source><![CDATA["
"float4 fileTexturePluginFragment(float2 uv, texture2D map, sampler2D mapSampler) \n"
"{ \n"
" uv -= floor(uv); \n"
" uv.y = 1.0f - uv.y; \n"
" float4 color = tex2D(mapSampler, uv); \n"
" return color.rgba; \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.000000\">"
" <function_name val=\"fileTexturePluginFragment\" />"
" <source><![CDATA["
"float4 fileTexturePluginFragment(float2 uv, Texture2D map, sampler mapSampler) \n"
"{ \n"
" uv -= floor(uv); \n"
" uv.y = 1.0f - uv.y; \n"
" float4 color = map.Sample(mapSampler, uv); \n"
" return color.rgba; \n"
"} \n]]>"
" </source>"
" </implementation>"
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
" <function_name val=\"fileTexturePluginFragment\" />"
" <source><![CDATA["
"float4 fileTexturePluginFragment(vec2 uv, sampler2D mapSampler) \n"
"{ \n"
" uv -= floor(uv); \n"
" uv.y = 1.0f - uv.y; \n"
" vec4 color = texture(mapSampler, uv); \n"
" return color.rgba; \n"
"} \n]]>"
" </source>"
" </implementation>"
" </implementation>"
"</fragment>";
// Register fragments with the manager if needed
//
MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
if (theRenderer)
{
MHWRender::MFragmentManager* fragmentMgr =
theRenderer->getFragmentManager();
if (fragmentMgr)
{
// Add fragments if needed
bool fragAdded = fragmentMgr->hasFragment(sFragmentName);
if (!fragAdded)
{
fragAdded = (sFragmentName == fragmentMgr->addShadeFragmentFromBuffer(sFragmentBody, false));
}
if (fragAdded)
{
fFragmentName = sFragmentName;
TRACE_API_CALLS("Added Fragment");
}
}
}
}
void createCustomMappings()
{
// Set up some mappings for the parameters on the file texture fragment,
// there is no correspondence to attributes on the node for the texture
// parameters.
MHWRender::MAttributeParameterMapping mapMapping(
"map", "", false, true);
mappings.append(mapMapping);
MHWRender::MAttributeParameterMapping textureSamplerMapping(
"textureSampler", "", false, true);
mappings.append(textureSamplerMapping);
}
And I called them in the createShaderInstance
void createShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::createShaderInstance");
MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
const MHWRender::MShaderManager* shaderMgr = renderer ? renderer->getShaderManager() : NULL;
if (!shaderMgr)
return;
initializeFragmentShaders();
createCustomMappings();
if (!fColorShaderInstance)
{
fColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
fColorShaderInstance->addInputFragment(fFragmentName, MString("output"), MString("diffuseColor"));
}
if (!fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance = shaderMgr->getStockShader( MHWRender::MShaderManager::k3dBlinnShader );
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
}
Then, I modified updateShaderInstance,
void updateShaderInstance()
{
TRACE_API_CALLS("vp2BlinnShaderOverride::updateShaderInstance");
if (fColorShaderInstance)
{
// Update shader to mark it as drawing with transparency or not.
fColorShaderInstance->setIsTransparent( isTransparent() );
//Replace diffuse update with fragment parameters update
//fColorShaderInstance->setParameter("diffuseColor", &fDiffuse[0] );
updateShader();
fColorShaderInstance->setParameter("specularColor", &fSpecular[0] );
}
if (fNonTexturedColorShaderInstance)
{
fNonTexturedColorShaderInstance->setParameter("diffuseColor", &fNonTextured[0]);
}
}
void updateShader()
{
TRACE_API_CALLS("Update texture");
MHWRender::MRenderer *renderer = MHWRender::MRenderer::theRenderer();
fFragmentTextureShader = fColorShaderInstance;
if(!fFragmentTextureShader)
{
TRACE_API_CALLS("Can't get fragment texture");
return;
}
// A random png file on my disk
MString fFileName("D:\\screenshot.png");
if (fResolvedMapName.length() == 0)
{
const MHWRender::MAttributeParameterMapping* mapping =
mappings.findByParameterName("map");
if (mapping)
{
TRACE_API_CALLS("Resolved mapping parameter");
fResolvedMapName = mapping->resolvedParameterName();
}
}
if (fResolvedSamplerName.length() == 0)
{
const MHWRender::MAttributeParameterMapping* mapping =
mappings.findByParameterName("textureSampler");
if (mapping)
{
TRACE_API_CALLS("Resolved texture sampler");
fResolvedSamplerName = mapping->resolvedParameterName();
}
}
// Set the parameters on the shader
if (fResolvedMapName.length() > 0 && fResolvedSamplerName.length() > 0)
{
// Set sampler to linear-wrap
if (!fSamplerState)
{
MHWRender::MSamplerStateDesc desc;
desc.filter = MHWRender::MSamplerState::kAnisotropic;
desc.maxAnisotropy = 16;
fSamplerState = MHWRender::MStateManager::acquireSamplerState(desc);
}
if (fSamplerState)
{
TRACE_API_CALLS("Update sampler parameter");
fFragmentTextureShader->setParameter(fResolvedSamplerName, *fSamplerState);
}
// Set texture
MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer();
if (renderer)
{
MHWRender::MTextureManager* textureManager =
renderer->getTextureManager();
if (textureManager)
{
MHWRender::MTexture* texture =
textureManager->acquireTexture(fFileName);
if (texture)
{
MHWRender::MTextureAssignment textureAssignment;
textureAssignment.texture = texture;
TRACE_API_CALLS("Update texture parameter");
fFragmentTextureShader->setParameter(fResolvedMapName, textureAssignment);
// release our reference now that it is set on the shader
textureManager->releaseTexture(texture);
}
}
}
}
}
At last, we need to add geometry texture to the shader since we can't update UV directly. Add following codes in the initialize
MHWRender::MVertexBufferDescriptor textureDesc(
empty, // Better to have a name here
MHWRender::MGeometry::kTexture,
MHWRender::MGeometry::kFloat,
2);
addGeometryRequirement(textureDesc);
It should be working now.