├── .gitignore ├── AEdx11ShaderTemplate.mel ├── D3DX11Effects.lib ├── LICENSE ├── README.md ├── crackFreePrimitiveGenerator.cpp ├── crackFreePrimitiveGenerator.h ├── dx11ConeAngleToHotspotConverter.cpp ├── dx11ConeAngleToHotspotConverter.h ├── dx11Shader.cpp ├── dx11Shader.h ├── dx11Shader.sln ├── dx11Shader.vcxproj ├── dx11ShaderCmd.cpp ├── dx11ShaderCmd.h ├── dx11ShaderCompileHelper.cpp ├── dx11ShaderCompileHelper.h ├── dx11ShaderCreateUI.mel ├── dx11ShaderInitStrings.mel ├── dx11ShaderOverride.cpp ├── dx11ShaderOverride.h ├── dx11ShaderPluginMain.cpp ├── dx11ShaderSemantics.cpp ├── dx11ShaderSemantics.h ├── dx11ShaderStrings.cpp ├── dx11ShaderStrings.h ├── dx11ShaderUniformParamBuilder.cpp ├── dx11ShaderUniformParamBuilder.h ├── dx11Shader_defaults.mel └── dx11Shader_initUI.mel /.gitignore: -------------------------------------------------------------------------------- 1 | # VS file/folders 2 | [Dd]ebug/ 3 | [Rr]elease/ 4 | [Hh]ybrid/ 5 | *.suo 6 | *.sdf 7 | 8 | # Compiled Object files 9 | *.slo 10 | *.lo 11 | *.o 12 | *.obj 13 | 14 | # Precompiled Headers 15 | *.gch 16 | *.pch 17 | 18 | # Compiled Dynamic libraries 19 | *.so 20 | *.dylib 21 | *.dll 22 | 23 | # Fortran module files 24 | *.mod 25 | 26 | # Compiled Static libraries 27 | *.lai 28 | *.la 29 | *.a 30 | #*.lib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | -------------------------------------------------------------------------------- /D3DX11Effects.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ADN-DevTech/Maya-dx11Shader-Sample/5401d2dea2e6587c387ff66bfd282567199dd2cb/D3DX11Effects.lib -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c), Autodesk, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Maya dx11Shader Sample 2 | ====================== 3 | 4 | This sample is the Maya source code for the "C:\Program Files\Autodesk\Maya2015\bin\plug-ins\dx11Shader.mll" plug-in. 5 | 6 | Information about dx11Shader in Maya: 7 | 8 | - http://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2015/ENU/Maya/files/GUID-21D2A020-EC76-4679-B38A-D5270CE52566-htm.html 9 | - http://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2015/ENU/Maya/files/GUID-EE108A86-9830-455E-BF2F-64A4075E8303-htm.html 10 | 11 | 12 | 13 | Dependencies 14 | -------------------- 15 | This sample is dependent of the DirectX June 2010 SDK version. 16 | 17 | The D3DX11Effects.lib is a modified version of the DirectX effects component from the DirectX June 2010 SDK version. 18 | 19 | See https://fx11.codeplex.com/license for details. 20 | 21 | 22 | Building the sample 23 | --------------------------- 24 | 25 | The sample was created using Visual Studio 2012 Update 4. 26 | 27 | - Load the .sln or .vcxproj in Visual Studio and build either the Hybrid (e.q. Debug) or Release version. There is no Debug Effect component library provided as this time, so use Hybrid whenever you want to build the Debug version of your dx11Shader version. 28 | - Copy the x64/[Hybrid | Release]/dx11Shader.mll into "C:\Program Files\Autodesk\Maya2015\bin\plug-ins\" 29 | - Start Maya and load the plug-in in Maya via the loadPlugin command or the Plug-in manager 30 | 31 | 32 | ## License 33 | 34 | This sample is licensed under the terms of the [MIT License](http://opensource.org/licenses/MIT). Please see the [LICENSE](LICENSE) file for full details. 35 | -------------------------------------------------------------------------------- /crackFreePrimitiveGenerator.cpp: -------------------------------------------------------------------------------- 1 | //- 2 | // ========================================================================== 3 | // Copyright 2012 Autodesk, Inc. All rights reserved. 4 | // 5 | // Use of this software is subject to the terms of the Autodesk 6 | // license agreement provided at the time of installation or download, 7 | // or which otherwise accompanies this software in either electronic 8 | // or hard copy form. 9 | // ========================================================================== 10 | //+ 11 | 12 | // Example plugin: crackFreePrimitiveGenerator.cpp 13 | // 14 | // This plug-in is an example of a custom MPxIndexBufferMutator. 15 | // It provides custom primitives based on shader requirements coming from 16 | // an MPxShaderOverride. The name() in the MIndexBufferDescriptor is used 17 | // to signify a unique identifier for a custom buffer. 18 | 19 | #include "crackFreePrimitiveGenerator.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace 31 | { 32 | struct Edge 33 | { 34 | Edge(unsigned int v0_ = 0, unsigned int v1_ = 0) : v0(v0_), v1(v1_) {} 35 | 36 | Edge reversed() const 37 | { 38 | return Edge(v1, v0); 39 | } 40 | 41 | bool isEqual(const Edge &rhs) const 42 | { 43 | return (v0 == rhs.v0 && v1 == rhs.v1); 44 | } 45 | 46 | bool isReverse(const Edge &rhs) const 47 | { 48 | return (v0 == rhs.v1 && v1 == rhs.v0); 49 | } 50 | 51 | unsigned int v0; 52 | unsigned int v1; 53 | }; 54 | 55 | bool operator< (const Edge& lhs, const Edge& rhs) 56 | { 57 | return (lhs.v0 < rhs.v0) || (lhs.v0 == rhs.v0 && lhs.v1 < rhs.v1); 58 | } 59 | 60 | class EdgeMapping 61 | { 62 | public: 63 | EdgeMapping(); 64 | 65 | void addTriangle(unsigned int faceVertexId0, unsigned int faceVertexId1, unsigned int faceVertexId2, unsigned int polyVertexId0, unsigned int polyVertexId1, unsigned int polyVertexId2); 66 | void addEdge(const Edge& faceEdge, const Edge& polyEdge); 67 | 68 | void addPositionUV(unsigned int faceVertexId, unsigned int polyVertexId, float u, float v); 69 | 70 | bool adjacentEdge(const Edge& faceEdge, Edge& adjacentEdge) const; 71 | 72 | bool dominantEdge(const Edge& faceEdge, Edge& dominantEdge) const; 73 | 74 | bool dominantPosition(unsigned int faceVertexId, unsigned int& dominantVertexId) const; 75 | 76 | private: 77 | // Map each face edge to its polygon edge. 78 | typedef std::map< Edge, Edge > FaceEdge2PolyEdgeMap; 79 | FaceEdge2PolyEdgeMap fFaceEdge2PolyEdgeMap; 80 | 81 | // Map each poly edge to both face edges that match. 82 | typedef std::map< Edge, std::pair< Edge, Edge > > PolyEdge2FaceEdgeMap; 83 | PolyEdge2FaceEdgeMap fPolyEdge2FaceEdgesMap; 84 | 85 | // Map a single face vertex id to its polygon vertex id. 86 | typedef std::map< unsigned int, unsigned int > FaceVertex2PolyVertexMap; 87 | FaceVertex2PolyVertexMap fFaceVertex2PolyVertexMap; 88 | 89 | // Map dominant vertex position via lowest uv coords. 90 | typedef std::pair< unsigned int, std::pair< float, float > > VertexUVPair; 91 | typedef std::map< unsigned int, VertexUVPair > PolyVertex2FaceVertexUVMap; 92 | PolyVertex2FaceVertexUVMap fPolyVertex2FaceVertexUVMap; 93 | }; 94 | 95 | EdgeMapping::EdgeMapping() 96 | { 97 | } 98 | 99 | void EdgeMapping::addTriangle(unsigned int faceVertexId0, unsigned int faceVertexId1, unsigned int faceVertexId2, unsigned int polyVertexId0, unsigned int polyVertexId1, unsigned int polyVertexId2) 100 | { 101 | addEdge( Edge(faceVertexId0, faceVertexId1), Edge(polyVertexId0, polyVertexId1) ); 102 | addEdge( Edge(faceVertexId1, faceVertexId2), Edge(polyVertexId1, polyVertexId2) ); 103 | addEdge( Edge(faceVertexId2, faceVertexId0), Edge(polyVertexId2, polyVertexId0) ); 104 | } 105 | 106 | // Add a new edge 107 | // The edge is represented by two associated vertex ids pairs : one in face vertices array space and a second in polygon face vertices array space. 108 | void EdgeMapping::addEdge(const Edge& faceEdge, const Edge& polyEdge) 109 | { 110 | if(polyEdge.v1 < polyEdge.v0) 111 | { 112 | // Revert edges 113 | Edge faceEdgeR = faceEdge.reversed(); 114 | Edge polyEdgeR = polyEdge.reversed(); 115 | addEdge(faceEdgeR, polyEdgeR); 116 | return; 117 | } 118 | 119 | fFaceEdge2PolyEdgeMap[faceEdge] = polyEdge; 120 | 121 | PolyEdge2FaceEdgeMap::iterator itP2F = fPolyEdge2FaceEdgesMap.find( polyEdge ); 122 | if(itP2F == fPolyEdge2FaceEdgesMap.end()) 123 | { 124 | fPolyEdge2FaceEdgesMap[polyEdge] = std::make_pair( faceEdge, faceEdge ); 125 | } 126 | else 127 | { 128 | itP2F->second.second = faceEdge; 129 | } 130 | } 131 | 132 | void EdgeMapping::addPositionUV(unsigned int faceVertexId, unsigned int polyVertexId, float u, float v) 133 | { 134 | fFaceVertex2PolyVertexMap[faceVertexId] = polyVertexId; 135 | 136 | PolyVertex2FaceVertexUVMap::iterator it = fPolyVertex2FaceVertexUVMap.find(polyVertexId); 137 | if(it == fPolyVertex2FaceVertexUVMap.end()) 138 | { 139 | fPolyVertex2FaceVertexUVMap[polyVertexId] = std::make_pair( faceVertexId, std::make_pair(u,v) ); 140 | } 141 | else 142 | { 143 | VertexUVPair& vertexUVPair = it->second; 144 | float lastU = vertexUVPair.second.first; 145 | float lastV = vertexUVPair.second.second; 146 | if( u < lastU || ( u == lastU && v < lastV ) ) 147 | { 148 | vertexUVPair.first = faceVertexId; 149 | vertexUVPair.second = std::make_pair(u,v); 150 | } 151 | } 152 | } 153 | 154 | // Find the adjacent edge that is shared between two faces. 155 | // The matching is done through the polygon vertex ids. 156 | // The returning edge have vertices in face space. 157 | bool EdgeMapping::adjacentEdge(const Edge& faceEdge, Edge& adjacentEdge) const 158 | { 159 | FaceEdge2PolyEdgeMap::const_iterator itF2P = fFaceEdge2PolyEdgeMap.find( faceEdge ); 160 | if(itF2P == fFaceEdge2PolyEdgeMap.end()) 161 | { 162 | Edge faceEdgeR = faceEdge.reversed(); 163 | itF2P = fFaceEdge2PolyEdgeMap.find( faceEdgeR ); 164 | if(itF2P == fFaceEdge2PolyEdgeMap.end()) 165 | return false; 166 | } 167 | 168 | const Edge& polyEdge = itF2P->second; 169 | 170 | PolyEdge2FaceEdgeMap::const_iterator itP2F = fPolyEdge2FaceEdgesMap.find( polyEdge ); 171 | if(itP2F == fPolyEdge2FaceEdgesMap.end()) 172 | return false; 173 | 174 | const Edge& faceEdge0 = itP2F->second.first; 175 | const Edge& faceEdge1 = itP2F->second.second; 176 | 177 | bool foundMatch = false; 178 | if(faceEdge.isEqual(faceEdge0)) 179 | { 180 | adjacentEdge = faceEdge1; 181 | foundMatch = true; 182 | } 183 | else if(faceEdge.isReverse(faceEdge0)) 184 | { 185 | adjacentEdge = faceEdge1.reversed(); 186 | foundMatch = true; 187 | } 188 | else if(faceEdge.isEqual(faceEdge1)) 189 | { 190 | adjacentEdge = faceEdge0; 191 | foundMatch = true; 192 | } 193 | else if(faceEdge.isReverse(faceEdge1)) 194 | { 195 | adjacentEdge = faceEdge0.reversed(); 196 | foundMatch = true; 197 | } 198 | 199 | return foundMatch; 200 | } 201 | 202 | bool EdgeMapping::dominantEdge(const Edge& faceEdge, Edge& dominantEdge) const 203 | { 204 | bool returnReversed = true; 205 | FaceEdge2PolyEdgeMap::const_iterator itF2P = fFaceEdge2PolyEdgeMap.find( faceEdge ); 206 | if(itF2P == fFaceEdge2PolyEdgeMap.end()) 207 | { 208 | Edge faceEdgeR = faceEdge.reversed(); 209 | itF2P = fFaceEdge2PolyEdgeMap.find( faceEdgeR ); 210 | if(itF2P == fFaceEdge2PolyEdgeMap.end()) 211 | return false; 212 | returnReversed = false; 213 | } 214 | 215 | const Edge& polyEdge = itF2P->second; 216 | 217 | PolyEdge2FaceEdgeMap::const_iterator itP2F = fPolyEdge2FaceEdgesMap.find( polyEdge ); 218 | if(itP2F == fPolyEdge2FaceEdgesMap.end()) 219 | return false; 220 | 221 | const Edge& faceEdge0 = itP2F->second.first; 222 | const Edge& faceEdge1 = itP2F->second.second; 223 | 224 | if(faceEdge0 < faceEdge1) 225 | { 226 | dominantEdge = (returnReversed ? faceEdge0.reversed() : faceEdge0); 227 | } 228 | else 229 | { 230 | dominantEdge = (returnReversed ? faceEdge1.reversed() : faceEdge1); 231 | } 232 | 233 | return true; 234 | } 235 | 236 | bool EdgeMapping::dominantPosition(unsigned int faceVertexId, unsigned int& dominantVertexId) const 237 | { 238 | FaceVertex2PolyVertexMap::const_iterator itF2P = fFaceVertex2PolyVertexMap.find(faceVertexId); 239 | if(itF2P == fFaceVertex2PolyVertexMap.end()) 240 | return false; 241 | 242 | unsigned polyVertexId = itF2P->second; 243 | 244 | PolyVertex2FaceVertexUVMap::const_iterator itP2FUV = fPolyVertex2FaceVertexUVMap.find(polyVertexId); 245 | if(itP2FUV == fPolyVertex2FaceVertexUVMap.end()) 246 | return false; 247 | 248 | dominantVertexId = itP2FUV->second.first; 249 | return true; 250 | } 251 | 252 | struct VertexF 253 | { 254 | static const float kTolerance; 255 | VertexF(const float* buffer, unsigned int index) 256 | { 257 | unsigned int bufferPos = index * 3; 258 | x = buffer[bufferPos++]; 259 | y = buffer[bufferPos++]; 260 | z = buffer[bufferPos++]; 261 | } 262 | 263 | bool isEqual(const VertexF &rhs) const 264 | { 265 | return (fabs(x - rhs.x) < kTolerance && fabs(y - rhs.y) < kTolerance && fabs(z - rhs.z) < kTolerance); 266 | } 267 | 268 | float x, y, z; 269 | }; 270 | 271 | const float VertexF::kTolerance = 1e-5f; 272 | 273 | bool operator< (const VertexF& lhs, const VertexF& rhs) 274 | { 275 | return ((lhs.x - rhs.x) < -VertexF::kTolerance) || 276 | (fabs(lhs.x - rhs.x) < VertexF::kTolerance && (lhs.y - rhs.y) < -VertexF::kTolerance) || 277 | (fabs(lhs.x - rhs.x) < VertexF::kTolerance && fabs(lhs.y - rhs.y) < VertexF::kTolerance && (lhs.z - rhs.z) < -VertexF::kTolerance); 278 | } 279 | 280 | struct VertexFMap 281 | { 282 | unsigned int getVertexId( const VertexF& v ); 283 | 284 | typedef std::map TVtxMap; 285 | TVtxMap vertexMap; 286 | }; 287 | 288 | unsigned int VertexFMap::getVertexId( const VertexF& v ) 289 | { 290 | VertexFMap::TVtxMap::const_iterator itVtx = vertexMap.find(v); 291 | if (itVtx != vertexMap.end()) 292 | return itVtx->second; 293 | unsigned int nextId = (unsigned int)vertexMap.size(); 294 | vertexMap.insert(TVtxMap::value_type(v,nextId)); 295 | return nextId; 296 | } 297 | } 298 | 299 | // Mode 1 : PN Triangles; no divergent normals and no displacement crack fix 300 | // Mode 2 : PN AEN, divergent normals crack fix; no displacement UV seam crack fix 301 | // Mode 3 : PN AEN, crack fix for divergent normals and UV seam displacement 302 | 303 | 304 | CrackFreePrimitiveGenerator::CrackFreePrimitiveGenerator(bool addAdjacentEdges, bool addDominantEdges, bool addDominantPosition) 305 | : fAddAdjacentEdges(addAdjacentEdges) 306 | , fAddDominantEdges(addDominantEdges) 307 | , fAddDominantPosition(addDominantPosition) 308 | { 309 | } 310 | 311 | CrackFreePrimitiveGenerator::~CrackFreePrimitiveGenerator() {} 312 | 313 | unsigned int CrackFreePrimitiveGenerator::computeTriangleSize(bool bAddAdjacentEdges, 314 | bool bAddDominantEdges, 315 | bool bAddDominantPosition) 316 | { 317 | return 3 /* triangles vertices */ 318 | + (bAddAdjacentEdges ? 3 * 2 : 0) /* adjacent edges */ 319 | + (bAddDominantEdges ? 3 * 2 : 0) /* dominant edges */ 320 | + (bAddDominantPosition ? 3 : 0); /* dominant position */ 321 | } 322 | 323 | void CrackFreePrimitiveGenerator::mutateIndexBuffer( const MUintArray& originalBufferIndices, 324 | const float* positionBufferFloat, 325 | const float* uvBufferFloat, 326 | bool bAddAdjacentEdges, 327 | bool bAddDominantEdges, 328 | bool bAddDominantPosition, 329 | MHWRender::MGeometry::DataType indexBufferDataType, 330 | void* indexData ) 331 | { 332 | unsigned int numTriVerts = originalBufferIndices.length(); 333 | 334 | EdgeMapping edges; 335 | { 336 | VertexFMap vertexMap; 337 | 338 | // Iterate all triangles found in the old index buffer: 339 | unsigned int vertexIndex = 0; 340 | 341 | while (vertexIndex < numTriVerts) 342 | { 343 | unsigned int faceVertexId0 = originalBufferIndices[vertexIndex++]; 344 | unsigned int polyVertexId0 = vertexMap.getVertexId(VertexF(positionBufferFloat, faceVertexId0)); 345 | 346 | unsigned int faceVertexId1 = originalBufferIndices[vertexIndex++]; 347 | unsigned int polyVertexId1 = vertexMap.getVertexId(VertexF(positionBufferFloat, faceVertexId1)); 348 | 349 | unsigned int faceVertexId2 = originalBufferIndices[vertexIndex++]; 350 | unsigned int polyVertexId2 = vertexMap.getVertexId(VertexF(positionBufferFloat, faceVertexId2)); 351 | 352 | edges.addTriangle(faceVertexId0, faceVertexId1, faceVertexId2, polyVertexId0, polyVertexId1, polyVertexId2); 353 | 354 | if(bAddDominantPosition && uvBufferFloat) 355 | { 356 | unsigned int uvIndex; 357 | uvIndex = faceVertexId0 * 2; 358 | edges.addPositionUV(faceVertexId0, polyVertexId0, uvBufferFloat[uvIndex], uvBufferFloat[uvIndex+1]); 359 | 360 | uvIndex = faceVertexId1 * 2; 361 | edges.addPositionUV(faceVertexId1, polyVertexId1, uvBufferFloat[uvIndex], uvBufferFloat[uvIndex+1]); 362 | 363 | uvIndex = faceVertexId2 * 2; 364 | edges.addPositionUV(faceVertexId2, polyVertexId2, uvBufferFloat[uvIndex], uvBufferFloat[uvIndex+1]); 365 | } 366 | } 367 | } 368 | 369 | unsigned int newTriId = 0; 370 | for(unsigned int triId = 0; triId < numTriVerts; ) 371 | { 372 | unsigned int vertexId0 = originalBufferIndices[triId++]; 373 | unsigned int vertexId1 = originalBufferIndices[triId++]; 374 | unsigned int vertexId2 = originalBufferIndices[triId++]; 375 | 376 | if (indexBufferDataType == MHWRender::MGeometry::kUnsignedInt32) { 377 | // Triangle vertices 378 | ((unsigned int*)indexData)[newTriId++] = vertexId0; 379 | ((unsigned int*)indexData)[newTriId++] = vertexId1; 380 | ((unsigned int*)indexData)[newTriId++] = vertexId2; 381 | 382 | // Adjacent edges 383 | if(bAddAdjacentEdges) 384 | { 385 | Edge adjacentEdge; 386 | 387 | // Edge0 : vertexId0 - vertexId1 388 | edges.adjacentEdge(Edge(vertexId0, vertexId1), adjacentEdge); 389 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v0; 390 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v1; 391 | 392 | // Edge1 : vertexId1 - vertexId2 393 | edges.adjacentEdge(Edge(vertexId1, vertexId2), adjacentEdge); 394 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v0; 395 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v1; 396 | 397 | // Edge2 : vertexId2 - vertexId0 398 | edges.adjacentEdge(Edge(vertexId2, vertexId0), adjacentEdge); 399 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v0; 400 | ((unsigned int*)indexData)[newTriId++] = adjacentEdge.v1; 401 | } 402 | 403 | // Dominant edges 404 | if(bAddDominantEdges) 405 | { 406 | Edge dominantEdge; 407 | 408 | // Edge0 : vertexId0 - vertexId1 409 | edges.dominantEdge(Edge(vertexId0, vertexId1), dominantEdge); 410 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v0; 411 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v1; 412 | 413 | // Edge1 : vertexId1 - vertexId2 414 | edges.dominantEdge(Edge(vertexId1, vertexId2), dominantEdge); 415 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v0; 416 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v1; 417 | 418 | // Edge2 : vertexId2 - vertexId0 419 | edges.dominantEdge(Edge(vertexId2, vertexId0), dominantEdge); 420 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v0; 421 | ((unsigned int*)indexData)[newTriId++] = dominantEdge.v1; 422 | } 423 | 424 | // Dominant position 425 | if(bAddDominantPosition) 426 | { 427 | unsigned int dominantVertexId; 428 | 429 | edges.dominantPosition(vertexId0, dominantVertexId); 430 | ((unsigned int*)indexData)[newTriId++] = dominantVertexId; 431 | 432 | edges.dominantPosition(vertexId1, dominantVertexId); 433 | ((unsigned int*)indexData)[newTriId++] = dominantVertexId; 434 | 435 | edges.dominantPosition(vertexId2, dominantVertexId); 436 | ((unsigned int*)indexData)[newTriId++] = dominantVertexId; 437 | } 438 | } 439 | else if (indexBufferDataType == MHWRender::MGeometry::kUnsignedChar) { 440 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId0; 441 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId1; 442 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)vertexId2; 443 | 444 | // Adjacent edges 445 | if(bAddAdjacentEdges) 446 | { 447 | Edge adjacentEdge; 448 | 449 | // Edge0 : vertexId0 - vertexId1 450 | edges.adjacentEdge(Edge(vertexId0, vertexId1), adjacentEdge); 451 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v0; 452 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v1; 453 | 454 | // Edge1 : vertexId1 - vertexId2 455 | edges.adjacentEdge(Edge(vertexId1, vertexId2), adjacentEdge); 456 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v0; 457 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v1; 458 | 459 | // Edge2 : vertexId2 - vertexId0 460 | edges.adjacentEdge(Edge(vertexId2, vertexId0), adjacentEdge); 461 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v0; 462 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)adjacentEdge.v1; 463 | } 464 | 465 | // Dominant edges 466 | if(bAddDominantEdges) 467 | { 468 | Edge dominantEdge; 469 | 470 | // Edge0 : vertexId0 - vertexId1 471 | edges.dominantEdge(Edge(vertexId0, vertexId1), dominantEdge); 472 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v0; 473 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v1; 474 | 475 | // Edge1 : vertexId1 - vertexId2 476 | edges.dominantEdge(Edge(vertexId1, vertexId2), dominantEdge); 477 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v0; 478 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v1; 479 | 480 | // Edge2 : vertexId2 - vertexId0 481 | edges.dominantEdge(Edge(vertexId2, vertexId0), dominantEdge); 482 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v0; 483 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantEdge.v1; 484 | } 485 | 486 | // Dominant position 487 | if(bAddDominantPosition) 488 | { 489 | unsigned int dominantVertexId; 490 | 491 | edges.dominantPosition(vertexId0, dominantVertexId); 492 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantVertexId; 493 | 494 | edges.dominantPosition(vertexId1, dominantVertexId); 495 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantVertexId; 496 | 497 | edges.dominantPosition(vertexId2, dominantVertexId); 498 | ((unsigned short*)indexData)[newTriId++] = (unsigned short)dominantVertexId; 499 | } 500 | } 501 | } 502 | } 503 | 504 | 505 | MHWRender::MGeometry::Primitive CrackFreePrimitiveGenerator::mutateIndexing(const MHWRender::MComponentDataIndexingList& sourceIndexBuffers, 506 | const MHWRender::MVertexBufferArray& vertexBuffers, 507 | MHWRender::MIndexBuffer& indexBuffer, 508 | int& primitiveStride) const 509 | { 510 | MHWRender::MVertexBuffer *positionBuffer = NULL; 511 | MHWRender::MVertexBuffer *uvBuffer = NULL; 512 | 513 | for (unsigned int ivb = 0; ivb < vertexBuffers.count() && (positionBuffer == NULL || uvBuffer == NULL); ++ivb) 514 | { 515 | MHWRender::MVertexBuffer *currBuffer = vertexBuffers.getBuffer(ivb); 516 | 517 | if (positionBuffer == NULL && currBuffer->descriptor().semantic() == MHWRender::MGeometry::kPosition) 518 | positionBuffer = currBuffer; 519 | 520 | if (uvBuffer == NULL && currBuffer->descriptor().semantic() == MHWRender::MGeometry::kTexture) 521 | uvBuffer = currBuffer; 522 | } 523 | 524 | if (positionBuffer == NULL) 525 | // We need at least the positions: 526 | return MHWRender::MGeometry::kInvalidPrimitive; 527 | 528 | float* positionBufferFloat = (float*)positionBuffer->map(); 529 | float* uvBufferFloat = NULL; 530 | if (uvBuffer) 531 | uvBufferFloat = (float*)uvBuffer->map(); 532 | 533 | for (int x = 0; x < sourceIndexBuffers.length(); ++x) 534 | { 535 | if (sourceIndexBuffers[x]->componentType() != MHWRender::MComponentDataIndexing::kFaceVertex) 536 | continue; 537 | 538 | const MUintArray& originalBufferIndices = sourceIndexBuffers[x]->indices(); 539 | unsigned int numTriVerts = originalBufferIndices.length(); 540 | 541 | unsigned int numTri = numTriVerts / 3; 542 | unsigned int triSize = computeTriangleSize(fAddAdjacentEdges, fAddDominantEdges, fAddDominantPosition); 543 | unsigned int bufferSize = numTri * triSize; 544 | 545 | void* indexData = indexBuffer.acquire(bufferSize, true /*writeOnly - we don't need the current buffer values*/); 546 | if (indexData != NULL) 547 | { 548 | mutateIndexBuffer( originalBufferIndices, positionBufferFloat, uvBufferFloat, 549 | fAddAdjacentEdges, fAddDominantEdges, fAddDominantPosition, 550 | indexBuffer.dataType(), indexData ); 551 | } 552 | 553 | if (positionBuffer) positionBuffer->unmap(); 554 | if (uvBuffer) uvBuffer->unmap(); 555 | indexBuffer.commit(indexData); 556 | primitiveStride = triSize; 557 | return MHWRender::MGeometry::kPatch; 558 | } 559 | 560 | if (positionBuffer) positionBuffer->unmap(); 561 | if (uvBuffer) uvBuffer->unmap(); 562 | return MHWRender::MGeometry::kInvalidPrimitive; 563 | } 564 | 565 | // This is the primitive generator creation function registered with the DrawRegistry. 566 | // Used to initialize a custom primitive generator. 567 | MHWRender::MPxIndexBufferMutator* CrackFreePrimitiveGenerator::createCrackFreePrimitiveGenerator18() 568 | { 569 | return new CrackFreePrimitiveGenerator(true /*addAdjacentEdges*/, true /*addDominantEdges*/, true /*addDominantPosition*/); 570 | } 571 | 572 | MHWRender::MPxIndexBufferMutator* CrackFreePrimitiveGenerator::createCrackFreePrimitiveGenerator9() 573 | { 574 | return new CrackFreePrimitiveGenerator(true /*addAdjacentEdges*/, false /*addDominantEdges*/, false /*addDominantPosition*/); 575 | } 576 | -------------------------------------------------------------------------------- /crackFreePrimitiveGenerator.h: -------------------------------------------------------------------------------- 1 | //- 2 | // ========================================================================== 3 | // Copyright 2012 Autodesk, Inc. All rights reserved. 4 | // 5 | // Use of this software is subject to the terms of the Autodesk 6 | // license agreement provided at the time of installation or download, 7 | // or which otherwise accompanies this software in either electronic 8 | // or hard copy form. 9 | // ========================================================================== 10 | //+ 11 | 12 | // Example plugin: crackFreePrimitiveGenerator.cpp 13 | // 14 | // This plug-in is an example of a custom MPxIndexBufferMutator. 15 | // It provides custom primitives based on shader requirements coming from 16 | // an MPxShaderOverride. The name() in the MIndexBufferDescriptor is used 17 | // to signify a unique identifier for a custom buffer. 18 | 19 | #include 20 | #include 21 | 22 | class MDagPath; 23 | class MObject; 24 | 25 | namespace MHWRender 26 | { 27 | class MComponentDataIndexingList; 28 | } 29 | 30 | class CrackFreePrimitiveGenerator : public MHWRender::MPxIndexBufferMutator 31 | { 32 | public: 33 | CrackFreePrimitiveGenerator(bool addAdjacentEdges, bool addDominantEdges, bool addDominantPosition); 34 | virtual ~CrackFreePrimitiveGenerator(); 35 | 36 | virtual MHWRender::MGeometry::Primitive mutateIndexing(const MHWRender::MComponentDataIndexingList& sourceIndexBuffers, 37 | const MHWRender::MVertexBufferArray& vertexBuffers, 38 | MHWRender::MIndexBuffer& mutatedBuffer, 39 | int& primitiveStride) const; 40 | 41 | // This will allow cleaning up the swatch for PNAEN geometries: 42 | static void mutateIndexBuffer( const MUintArray& originalBufferIndices, 43 | const float* positionBufferFloat, 44 | const float* uvBufferFloat, 45 | bool bAddAdjacentEdges, 46 | bool bAddDominantEdges, 47 | bool bAddDominantPosition, 48 | MHWRender::MGeometry::DataType indexBufferDataType, 49 | void* indexData ); 50 | 51 | static unsigned int computeTriangleSize( bool bAddAdjacentEdges, 52 | bool bAddDominantEdges, 53 | bool bAddDominantPosition); 54 | 55 | static MHWRender::MPxIndexBufferMutator* createCrackFreePrimitiveGenerator18(); 56 | static MHWRender::MPxIndexBufferMutator* createCrackFreePrimitiveGenerator9(); 57 | 58 | private: 59 | bool fAddAdjacentEdges; 60 | bool fAddDominantEdges; 61 | bool fAddDominantPosition; 62 | }; 63 | -------------------------------------------------------------------------------- /dx11ConeAngleToHotspotConverter.cpp: -------------------------------------------------------------------------------- 1 | //- 2 | // Copyright 2011 Autodesk, Inc. All rights reserved. 3 | // 4 | // Use of this software is subject to the terms of the Autodesk license 5 | // agreement provided at the time of installation or download, or which 6 | // otherwise accompanies this software in either electronic or hard copy form. 7 | //+ 8 | 9 | #if _MSC_VER >= 1700 10 | #pragma warning( disable: 4005 ) 11 | #endif 12 | 13 | 14 | #include "dx11ConeAngleToHotspotConverter.h" 15 | #include "dx11Shader.h" 16 | #include "dx11ShaderStrings.h" 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define McheckErr(stat,stringId) \ 31 | if ( MS::kSuccess != stat ) { \ 32 | MString msg = dx11ShaderStrings::getString(stringId); \ 33 | stat.perror(msg); \ 34 | return MS::kFailure; \ 35 | } 36 | 37 | static MObject sConeAngle; 38 | static MObject sPenumbraAngle; 39 | static MObject sHotspot; 40 | static MObject sFalloff; 41 | 42 | dx11ConeAngleToHotspotConverter::dx11ConeAngleToHotspotConverter() {} 43 | dx11ConeAngleToHotspotConverter::~dx11ConeAngleToHotspotConverter() {} 44 | 45 | void dx11ConeAngleToHotspotConverter::postConstructor( ) { 46 | setExistWithoutOutConnections(false); 47 | } 48 | 49 | MStatus dx11ConeAngleToHotspotConverter::compute( const MPlug& plug, MDataBlock& data ) 50 | { 51 | 52 | MStatus returnStatus; 53 | 54 | if ((plug == sHotspot) || (plug.parent() == sHotspot)) { 55 | MDataHandle coneAngleData = data.inputValue( sConeAngle, &returnStatus ); 56 | McheckErr(returnStatus,dx11ShaderStrings::kErrorConeAngle); 57 | 58 | MDataHandle forwardData = data.inputValue( sPenumbraAngle, &returnStatus ); 59 | McheckErr(returnStatus,dx11ShaderStrings::kErrorPenumbraAngle); 60 | 61 | double coneAngle = coneAngleData.asAngle().asRadians() / 2.0; 62 | double penumbraAngle = coneAngleData.asAngle().asRadians() / 2.0; 63 | double outputAngle = coneAngle; 64 | if (penumbraAngle < 0) 65 | outputAngle += penumbraAngle; 66 | 67 | MDataHandle outputRot = data.outputValue( sHotspot ); 68 | outputRot.set( outputAngle ); 69 | outputRot.setClean(); 70 | } 71 | else if ((plug == sFalloff) || (plug.parent() == sFalloff)) { 72 | MDataHandle coneAngleData = data.inputValue( sConeAngle, &returnStatus ); 73 | McheckErr(returnStatus,dx11ShaderStrings::kErrorConeAngle); 74 | 75 | MDataHandle penumbraAngleData = data.inputValue( sPenumbraAngle, &returnStatus ); 76 | McheckErr(returnStatus,dx11ShaderStrings::kErrorPenumbraAngle); 77 | 78 | double coneAngle = coneAngleData.asAngle().asRadians() / 2.0; 79 | double penumbraAngle = penumbraAngleData.asAngle().asRadians() / 2.0; 80 | double outputAngle = coneAngle; 81 | if (penumbraAngle > 0) 82 | outputAngle += penumbraAngle; 83 | 84 | MDataHandle outputRot = data.outputValue( sFalloff ); 85 | outputRot.set( outputAngle ); 86 | outputRot.setClean(); 87 | } else 88 | return MS::kUnknownParameter; 89 | 90 | return MS::kSuccess; 91 | } 92 | 93 | /* static */ 94 | MTypeId dx11ConeAngleToHotspotConverter::typeId() 95 | { 96 | // This typeid must be unique across the universe of Maya plug-ins. 97 | // The typeid is a unique 32bit indentifier that describes this node. 98 | // It is used to save and retrieve nodes of this type from the binary 99 | // file format. If it is not unique, it will cause file IO problems. 100 | static MTypeId sId( 0x00081055 ); 101 | return sId; 102 | } 103 | 104 | void* dx11ConeAngleToHotspotConverter::creator() 105 | { 106 | return new dx11ConeAngleToHotspotConverter(); 107 | } 108 | 109 | MStatus dx11ConeAngleToHotspotConverter::initialize() 110 | { 111 | MFnNumericAttribute nAttr; 112 | MFnUnitAttribute uAttr; 113 | MStatus stat; 114 | 115 | // Set up inputs 116 | // 117 | sConeAngle = uAttr.create( "coneAngle", "ca", MFnUnitAttribute::kAngle, 45.0 ); 118 | uAttr.setStorable(false); 119 | uAttr.setConnectable(true); 120 | sPenumbraAngle = uAttr.create( "penumbraAngle", "pa", MFnUnitAttribute::kAngle, 0.0 ); 121 | uAttr.setStorable(false); 122 | uAttr.setConnectable(true); 123 | 124 | // Set up outputs 125 | // 126 | sHotspot = nAttr.create( "hotspot", "hs", MFnNumericData::kDouble ); 127 | nAttr.setStorable(false); 128 | nAttr.setConnectable(true); 129 | sFalloff = nAttr.create( "falloff", "fo", MFnNumericData::kDouble ); 130 | nAttr.setStorable(false); 131 | nAttr.setConnectable(true); 132 | 133 | stat = addAttribute( sConeAngle ); 134 | if (!stat) { stat.perror("addAttribute"); return stat;} 135 | stat = addAttribute( sPenumbraAngle ); 136 | if (!stat) { stat.perror("addAttribute"); return stat;} 137 | stat = addAttribute( sHotspot ); 138 | if (!stat) { stat.perror("addAttribute"); return stat;} 139 | stat = addAttribute( sFalloff ); 140 | if (!stat) { stat.perror("addAttribute"); return stat;} 141 | 142 | stat = attributeAffects( sConeAngle, sHotspot ); 143 | if (!stat) { stat.perror("attributeAffects"); return stat;} 144 | stat = attributeAffects( sConeAngle, sFalloff ); 145 | if (!stat) { stat.perror("attributeAffects"); return stat;} 146 | stat = attributeAffects( sPenumbraAngle, sHotspot ); 147 | if (!stat) { stat.perror("attributeAffects"); return stat;} 148 | stat = attributeAffects( sPenumbraAngle, sFalloff ); 149 | if (!stat) { stat.perror("attributeAffects"); return stat;} 150 | 151 | return MS::kSuccess; 152 | } 153 | 154 | -------------------------------------------------------------------------------- /dx11ConeAngleToHotspotConverter.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ConeAngleToHotspotConverter_h_ 2 | #define _dx11ConeAngleToHotspotConverter_h_ 3 | //- 4 | // Copyright 2012 Autodesk, Inc. All rights reserved. 5 | // 6 | // Use of this software is subject to the terms of the Autodesk license agreement 7 | // provided at the time of installation or download, or which otherwise 8 | // accompanies this software in either electronic or hard copy form. 9 | //+ 10 | #include 11 | 12 | //////////////////////////////////////////////////////// 13 | // 14 | // Maya to OGS Spotlight cone converter node: 15 | // 16 | class dx11ConeAngleToHotspotConverter : public MPxNode 17 | { 18 | public: 19 | dx11ConeAngleToHotspotConverter(); 20 | virtual ~dx11ConeAngleToHotspotConverter(); 21 | 22 | virtual void postConstructor( ); 23 | virtual MStatus compute( const MPlug& plug, MDataBlock& data ); 24 | 25 | static MTypeId typeId(); 26 | static void* creator(); 27 | static MStatus initialize(); 28 | }; 29 | 30 | #endif /* _dx11ConeAngleToHotspotConverter_h_ */ 31 | -------------------------------------------------------------------------------- /dx11Shader.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ShaderNode_h_ 2 | #define _dx11ShaderNode_h_ 3 | //- 4 | // Copyright 2011 Autodesk, Inc. All rights reserved. 5 | // 6 | // Use of this software is subject to the terms of the Autodesk license agreement 7 | // provided at the time of installation or download, or which otherwise 8 | // accompanies this software in either electronic or hard copy form. 9 | //+ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | // Includes for DX11 21 | #define WIN32_LEAN_AND_MEAN 22 | #include 23 | 24 | // for VS 2012, Win8 SDK includes DX sdk with some header removed 25 | #if _MSC_VER >= 1700 26 | #include 27 | #else 28 | #include 29 | #endif 30 | 31 | #define HAVE_D3DX11EFFECT_LIBRARY_BUILT 32 | #if defined(HAVE_D3DX11EFFECT_LIBRARY_BUILT) 33 | // To build against the DX SDK header use the following commented line 34 | //#include <../Samples/C++/Effects11/Inc/d3dx11effect.h> 35 | #include 36 | #define dx11ShaderDX11Device ID3D11Device 37 | #define dx11ShaderDX11DeviceContext ID3D11DeviceContext 38 | #define dx11ShaderDX11Effect ID3DX11Effect 39 | #define dx11ShaderDX11EffectTechnique ID3DX11EffectTechnique 40 | #define dx11ShaderDX11Pass ID3DX11EffectPass 41 | #define dx11ShaderDX11InputLayout ID3D11InputLayout 42 | #define dx11ShaderDX11InputElementDesc D3D11_INPUT_ELEMENT_DESC 43 | #define dx11ShaderDX11EffectVariable ID3DX11EffectVariable 44 | #define dx11ShaderDX11EffectShaderResourceVariable ID3DX11EffectShaderResourceVariable 45 | #define dx11ShaderDX11RasterizerState ID3D11RasterizerState 46 | #define dx11ShaderDX11DepthStencilState ID3D11DepthStencilState 47 | #define dx11ShaderDX11BlendState ID3D11BlendState 48 | #else 49 | #define dx11ShaderDX11Device void 50 | #define dx11ShaderDX11DeviceContext void 51 | #define dx11ShaderDX11Effect void 52 | #define dx11ShaderDX11EffectTechnique void 53 | #define dx11ShaderDX11Pass void 54 | #define dx11ShaderDX11InputLayout void 55 | #define dx11ShaderDX11InputElementDesc void 56 | #define dx11ShaderDX11EffectVariable void 57 | #define dx11ShaderDX11EffectShaderResourceVariable void 58 | #define dx11ShaderDX11RasterizerState void 59 | #define dx11ShaderDX11DepthStencilState void 60 | #define dx11ShaderDX11BlendState void 61 | #endif 62 | #include 63 | #include 64 | #include 65 | 66 | class CUniformParameterBuilder; 67 | class MRenderProfile; 68 | 69 | namespace MHWRender { 70 | class MLightParameterInformation; 71 | class MTexture; 72 | class MRenderTarget; 73 | class MDrawContext; 74 | } 75 | 76 | #define USE_GL_TEXTURE_CACHING 77 | 78 | //////////////////////////////////////////////////////// 79 | // 80 | // Maya hardware shader node 81 | // 82 | class dx11ShaderNode : public MPxHardwareShader 83 | { 84 | public: 85 | // Identify the purpose of the current rendering process 86 | enum ERenderType 87 | { 88 | RENDER_SCENE, // Render the scene to the viewport 2.0 89 | RENDER_SWATCH, // Render the swatch that represents the current selected technique 90 | RENDER_SWATCH_PROXY, // Render a dummy swatch when no effect or no valid technique selected 91 | RENDER_UVTEXTURE, // Render a texture for the UV editor 92 | RENDER_SCENE_DEFAULT_LIGHT // Render the scene using a default light 93 | }; 94 | 95 | enum ELightType 96 | { 97 | eInvalidLight, 98 | eUndefinedLight, 99 | eSpotLight, 100 | ePointLight, 101 | eDirectionalLight, 102 | eAmbientLight, 103 | eVolumeLight, 104 | eAreaLight, 105 | eDefaultLight, 106 | 107 | eLightCount 108 | }; 109 | 110 | // Identify the transparency state of the selected technique 111 | enum ETransparencyState 112 | { 113 | eOpaque, // Technique is always opaque 114 | eTransparent, // Technique is always transparent 115 | eTestOpacitySemantics, // Technique transparency depends on the value of the float parameter with kOpacity semantic ( transparent if less than 1.0) 116 | eScriptedTest // Technique transparency depends on the result of the transparencyTest MEL procedure 117 | }; 118 | 119 | struct ContextStates 120 | { 121 | ContextStates() : rasterizerState(NULL), depthStencilState(NULL), blendState(NULL) {} 122 | 123 | dx11ShaderDX11RasterizerState* rasterizerState; 124 | dx11ShaderDX11DepthStencilState* depthStencilState; 125 | UINT stencilRef; 126 | dx11ShaderDX11BlendState* blendState; 127 | float blendFactor[4]; 128 | UINT sampleMask; 129 | }; 130 | 131 | class LightParameterInfo 132 | { 133 | typedef dx11ShaderNode::ELightType ELightType; 134 | 135 | public: 136 | LightParameterInfo(ELightType lightType = dx11ShaderNode::eInvalidLight, bool hasLightTypeSemantics = false); 137 | 138 | ELightType lightType() const; 139 | 140 | public: 141 | ELightType fLightType; 142 | bool fHasLightTypeSemantics; 143 | bool fIsDirty; 144 | 145 | // This is a mapindex, ELightParameterType> 146 | typedef std::map TConnectableParameters; 147 | TConnectableParameters fConnectableParameters; 148 | 149 | MObject fAttrUseImplicit; 150 | MObject fAttrConnectedLight; 151 | MObject fCachedImplicitLight; 152 | }; 153 | 154 | public: 155 | // Constructor/Destructor housekeeping: create, copy setup 156 | dx11ShaderNode(); 157 | virtual ~dx11ShaderNode(); 158 | 159 | static MTypeId typeId(); 160 | static void* creator(); 161 | static MStatus initialize(); 162 | static void initializeNodeAttrs(); 163 | 164 | // Query the renderers supported by this shader 165 | // 166 | virtual const MRenderProfile& profile(); 167 | 168 | public: 169 | // Internal attribute housekeeping 170 | virtual void copyInternalData( MPxNode* pSrc ); 171 | static void postDuplicateCB( void *data ); 172 | virtual bool getInternalValueInContext( const MPlug&,MDataHandle&,MDGContext&); 173 | virtual bool setInternalValueInContext( const MPlug&,const MDataHandle&,MDGContext&); 174 | 175 | virtual MStatus connectionMade( const MPlug& plug, const MPlug& otherPlug, bool asSrc ); 176 | 177 | // Dynamic light connection housekeeping: 178 | virtual MStatus setDependentsDirty(const MPlug & plugBeingDirtied, MPlugArray & affectedPlugs); 179 | 180 | ///////////////////////////////// 181 | // Topology Management 182 | public: 183 | bool rebuildAlways(size_t baseVersionId) const; 184 | bool isDirty(size_t baseVersionId) const; 185 | size_t geometryVersionId() const; 186 | 187 | private: 188 | bool hasUpdatedVaryingInput() const; 189 | void setTopoDirty(); 190 | 191 | ///////////////////////////////// 192 | // Effect Management 193 | public: 194 | static bool reloadAll(const MString& effectName); 195 | bool reload(); 196 | 197 | const MString& effectName() const; 198 | dx11ShaderDX11Effect* effect() const; 199 | 200 | double boundingBoxExtraScale() const; 201 | 202 | private: 203 | bool loadEffect( const MString& effectName ); 204 | 205 | bool loadFromFile( const MString& fileName, dx11ShaderDX11Device* dxDevice); 206 | bool loadFromBuffer( const MString& identifier, const void* pData, unsigned int dataSize, dx11ShaderDX11Device* dxDevice); 207 | 208 | bool initializeEffect(); 209 | void resetData(bool clearEffect = true); 210 | 211 | ///////////////////////////////// 212 | // Technique Management 213 | public: 214 | const MStringArray& techniques() const; 215 | inline int techniqueCount() const; 216 | 217 | bool techniqueIsTransparent() const; 218 | bool techniqueSupportsAdvancedTransparency() const; 219 | bool techniqueOverridesDrawState() const; 220 | 221 | // Does the technique know how to render shadows or other special context? 222 | bool techniqueHandlesContext(const MString& requestedContext) const; 223 | 224 | // Return the active technique number. Will be -1 if none 225 | int activeTechnique() const; 226 | 227 | // Return pointer to active technique 228 | dx11ShaderDX11EffectTechnique* technique() const; 229 | 230 | // Return name of active technique 231 | const MString& activeTechniqueName() const; 232 | 233 | // Return name of index buffer type of active technique 234 | const MString& techniqueIndexBufferType() const; 235 | 236 | private: 237 | bool initializeTechniques(); 238 | bool setTechnique( const MString& techniqueName ); 239 | bool setTechnique( int techniqueNumber ); 240 | 241 | void initTechniqueParameters(); 242 | 243 | void storeDefaultTextureNames(); 244 | void restoreDefaultTextureNames(); 245 | 246 | ///////////////////////////////// 247 | // Pass Management 248 | public: 249 | // Return the number of pass in active technique 250 | int passCount() const; 251 | 252 | private: 253 | dx11ShaderDX11Pass* activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int passId, ERenderType renderType ) const; 254 | dx11ShaderDX11Pass* activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int passId, const MStringArray& passSem, ERenderType renderType ) const; 255 | 256 | bool passHasHullShader(dx11ShaderDX11Pass* dxPass) const; 257 | dx11ShaderDX11InputLayout* getInputLayout(dx11ShaderDX11Device* dxDevice, dx11ShaderDX11Pass* dxPass, unsigned int numLayouts, const dx11ShaderDX11InputElementDesc* layoutDesc) const; 258 | 259 | ///////////////////////////////// 260 | // Rendering 261 | public: 262 | // Render to GL viewport 263 | virtual MStatus render( MGeometryList& iterator); 264 | 265 | // Override this method to draw a image for swatch rendering. 266 | /// 267 | virtual MStatus renderSwatchImage( MImage & image ); 268 | 269 | // Override these methods to support texture display in the UV texture editor. 270 | // 271 | virtual MStatus getAvailableImages( const MPxHardwareShader::ShaderContext &context, const MString& uvSetName, MStringArray &imageNames ); 272 | virtual MStatus renderImage( const MPxHardwareShader::ShaderContext &context, const MString& imageName, floatRegion region, const MPxHardwareShader::RenderParameters& parameters, int &imageWidth, int &imageHeight ); 273 | virtual MStatus renderImage( const MPxHardwareShader::ShaderContext &context, MHWRender::MUIDrawManager& uiDrawManager, const MString& imageName, floatRegion region, const MPxHardwareShader::RenderParameters& parameters, int &imageWidth, int &imageHeight ); 274 | 275 | // Render to DX vp2 276 | bool render(const MHWRender::MDrawContext& context, const MHWRender::MRenderItemList& renderItemList); 277 | 278 | private: 279 | typedef std::vector RenderItemList; 280 | 281 | // Render functions for a list of render items 282 | bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, 283 | unsigned int numPasses, const MStringArray& passSem, 284 | const RenderItemList& renderItemList, 285 | const MVaryingParameterList& varyingParameters, ERenderType renderType, const MString& indexBufferType) const; 286 | bool renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass, 287 | const RenderItemList& renderItemList, 288 | const MVaryingParameterList& varyingParameters, ERenderType renderType, const MString& indexBufferType) const; 289 | 290 | // Render functions for a single geometry 291 | bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses, 292 | const MHWRender::MGeometry* geometry, MHWRender::MGeometry::Primitive primitiveType, unsigned int primitiveStride, 293 | const MVaryingParameterList& varyingParameters, ERenderType renderType, const MString& indexBufferType ) const; 294 | 295 | bool renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass, 296 | const MHWRender::MGeometry* geometry, MHWRender::MGeometry::Primitive primitiveType, unsigned int primitiveStride, 297 | const MVaryingParameterList& varyingParameters, ERenderType renderType, const MString& indexBufferType) const; 298 | 299 | // Render function for a single geometry into a texture target 300 | bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses, 301 | MHWRender::MRenderTarget* textureTarget, unsigned int width, unsigned int height, float clearColor[4], 302 | const MHWRender::MGeometry* geometry, MHWRender::MGeometry::Primitive primitiveType, unsigned int primitiveStride, 303 | const MVaryingParameterList& varyingParameters, ERenderType renderType, const MString& indexBufferType) const; 304 | 305 | public: 306 | void backupStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states) const; 307 | void restoreStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states) const; 308 | 309 | private: 310 | typedef std::map< dx11ShaderDX11EffectShaderResourceVariable*, MHWRender::MTexture* > ResourceTextureMap; 311 | bool updateParameters( const MHWRender::MDrawContext& context, MUniformParameterList& uniformParameters, ResourceTextureMap &resourceTexture, ERenderType renderType ) const; 312 | void updateViewportGlobalParameters( const MHWRender::MDrawContext& context ) const; 313 | 314 | public: 315 | void updateShaderBasedGeoChanges(); 316 | 317 | private: 318 | typedef std::map TshadowFlagBackupState; 319 | void initShadowFlagBackupState(TshadowFlagBackupState& stateBackup ) const; 320 | void setPerGeometryShadowOnFlag(bool receivesShadows, TshadowFlagBackupState& stateBackup ) const; 321 | 322 | ///////////////////////////////// 323 | // Uniform and varying parameters 324 | public: 325 | void clearParameters(); 326 | 327 | private: 328 | // Uniform and varying parameters 329 | void preBuildUniformParameterList(); 330 | bool buildUniformParameterList(); 331 | bool buildVaryingParameterList(); 332 | 333 | bool buildVertexDescriptorFromVaryingParameters(); 334 | 335 | // Internal 336 | void initMayaParameters(); 337 | 338 | ///////////////////////////////// 339 | // Attibute Editor 340 | public: 341 | const MStringArray& getUIGroups() const; 342 | MStringArray getUIGroupParameters(int uiGroupIndex) const; 343 | int getIndexForUIGroupName(const MString& uiGroupName, bool appendGroup = false); 344 | 345 | const MStringArray& lightInfoDescription() const; 346 | 347 | MString getLightConnectionInfo(int lightIndex); 348 | MStringArray getLightableParameters(int lightIndex, bool showSemantics); 349 | int getIndexForLightName(const MString& lightName, bool appendLight = false); 350 | 351 | bool getVariableNameAsAttributeName(){ return fVariableNameAsAttributeName; } 352 | 353 | private: 354 | bool appendParameterNameIfVisible(int paramIndex, MStringArray& paramArray) const; 355 | 356 | ///////////////////////////////// 357 | // Light Management 358 | public: 359 | void refreshLightConnectionAttributes(bool inSceneUpdateNotification=false); 360 | 361 | void connectLight(int lightIndex, MDagPath light); 362 | void disconnectLight(int lightIndex); 363 | 364 | private: 365 | void refreshView() const; 366 | void setLightRequiresShadows(const MObject& lightObject, bool requiresShadow) const; 367 | void updateImplicitLightConnections(const MHWRender::MDrawContext& context, ERenderType renderType) const; 368 | void updateExplicitLightConnections(const MHWRender::MDrawContext& context, ERenderType renderType) const; 369 | 370 | private: 371 | void updateImplicitLightParameterCache(std::vector& builders); 372 | void clearLightConnectionData(); 373 | 374 | private: 375 | void getLightParametersToUpdate(std::set& parametersToUpdate, ERenderType renderType) const; 376 | 377 | void connectLight(const LightParameterInfo& lightInfo, MHWRender::MLightParameterInformation* lightParam, ERenderType renderType=RENDER_SCENE) const; 378 | bool connectExplicitAmbientLight(const LightParameterInfo& lightInfo, const MObject& sourceLight) const; 379 | void turnOffLight(const LightParameterInfo& lightInfo) const; 380 | void setLightParameterLocking(const LightParameterInfo& lightInfo, bool locked) const; 381 | 382 | ///////////////////////////////// 383 | // Texture Management 384 | private: 385 | MHWRender::MTexture* loadTexture(const MString& textureName, const MString& layerName, int alphaChannelIdx, int mipmapLevels) const; 386 | void releaseTexture(MHWRender::MTexture* texture) const; 387 | void assignTexture(dx11ShaderDX11EffectShaderResourceVariable* resourceVariable, const MString& textureName, const MString& layerName, int alphaChannelIdx, ResourceTextureMap& resourceTexture) const; 388 | void releaseAllTextures(ResourceTextureMap& resourceTexture) const; 389 | void releaseAllTextures(); 390 | 391 | MHWRender::MTexture* getUVTexture(MHWRender::MDrawContext *context, const MString& imageName, int& imageWidth, int& imageHeight); 392 | MHWRender::MTexture* getUVTexture(MHWRender::MDrawContext *context, const MString& imageName, int& imageWidth, int& imageHeight, 393 | MString &textureName, MString& layerName, int &alphaChannelIdx, int &mipmapLevels); 394 | 395 | public: 396 | bool getTextureFile(const MString& uniformName, MString& textureFile) const; 397 | 398 | ///////////////////////////////// 399 | // Convenient functions 400 | private: 401 | void setParameterAsVector(int paramIndex, float* data) const; 402 | void setParameterAsScalar(int paramIndex, float data) const; 403 | void setParameterAsScalar(int paramIndex, bool data) const; 404 | void setParameterAsScalar(int paramIndex, int data) const; 405 | void setParameterAsMatrix(int paramIndex, MMatrix& data) const; 406 | void setParameterAsResource(int paramIndex, ID3D11ShaderResourceView* inResource) const; 407 | void setParameterFromUniformAsVector(int paramIndex,const MHWRender::MDrawContext& context, const float *data = NULL) const; 408 | void setParameterFromUniformAsScalar(int paramIndex,const MHWRender::MDrawContext& context) const; 409 | 410 | ///////////////////////////////// 411 | public: 412 | const MHWRender::MVertexBufferDescriptorList* vertexBufferDescLists(); 413 | 414 | ///////////////////////////////// 415 | // Diagnostics/description strings 416 | private: 417 | void displayErrorAndWarnings() const; 418 | void reportInternalError( const char* function, size_t errcode ) const; 419 | 420 | ///////////////////////////////// 421 | // External content management 422 | private: 423 | #if defined(MAYA_WANT_EXTERNALCONTENTTABLE) 424 | virtual void getExternalContent(MExternalContentInfoTable& table) const; 425 | virtual void setExternalContent(const MExternalContentLocationTable& table); 426 | #endif 427 | 428 | private: 429 | // Version id, used by VP2.0 override to determine when a rebuild is necessary 430 | size_t fGeometryVersionId; 431 | 432 | // Keeps track if the anything in the shader may change the geo 433 | bool fShaderChangesGeo; 434 | double fLastTime; 435 | 436 | // Force the shader variable name to become the Maya attribute name, regardless of UIName annotation 437 | bool fVariableNameAsAttributeName; 438 | 439 | // Identifier to track scene-render-frame in order to optimize the updateParameter routine. 440 | mutable MUint64 fLastFrameStamp; 441 | 442 | // For duplicate 443 | dx11ShaderNode* fDuplicateNodeSource; 444 | MCallbackId fPostDuplicateCallBackId; 445 | MPlugArray fDuplicatedConnections; 446 | 447 | ///////////// Effect Management 448 | // Effect name 449 | MString fEffectName; 450 | // Pointer to effect 451 | dx11ShaderDX11Effect* fEffect; 452 | 453 | ///////////// Technique Management 454 | // List of techniques by name 455 | MStringArray fTechniqueNames; 456 | 457 | // Active technique index 458 | int fTechniqueIdx; 459 | // Active technique name 460 | MString fTechniqueName; 461 | // Pointer to active technique 462 | dx11ShaderDX11EffectTechnique* fTechnique; 463 | // Active technique mipmapLevels value when loading textures 464 | int fTechniqueTextureMipMapLevels; 465 | // Active technique custom primitive generator that will be used to generate the index buffer. 466 | MString fTechniqueIndexBufferType; 467 | 468 | ETransparencyState fTechniqueIsTransparent; 469 | MString fOpacityPlugName; 470 | MString fTransparencyTestProcName; 471 | bool fTechniqueSupportsAdvancedTransparency; 472 | bool fTechniqueOverridesDrawState; 473 | 474 | // The enum version of .technique attribute (node local dynamic attr) 475 | MObject fTechniqueEnumAttr; 476 | 477 | ///////////// Pass Management 478 | // Active technique pass count 479 | unsigned int fPassCount; 480 | 481 | ///////////// Uniform Parameters 482 | // List of uuniform parameters. 483 | MUniformParameterList fUniformParameters; 484 | 485 | ///////////// Varying Parameters 486 | // List of vertex buffer descriptions. 487 | MVaryingParameterList fVaryingParameters; 488 | MHWRender::MVertexBufferDescriptorList fVaryingParametersVertexDescriptorList; 489 | size_t fVaryingParametersGeometryVersionId; 490 | size_t fVaryingParametersUpdateId; 491 | 492 | // default UV editor textures 493 | MStringArray fDefaultTextureNames; 494 | 495 | ///////////// Light 496 | typedef std::vector LightParameterInfoVec; 497 | LightParameterInfoVec fLightParameters; 498 | MStringArray fLightNames; 499 | MStringArray fLightDescriptions; 500 | mutable int fImplicitAmbientLight; 501 | 502 | ///////////// Attibute Editor 503 | MStringArray fUIGroupNames; 504 | std::vector > fUIGroupParameters; 505 | 506 | ///////////// Texture Management 507 | ResourceTextureMap fResourceTextureMap; 508 | mutable bool fForceUpdateTexture; 509 | int fFixedTextureMipMapLevels; 510 | MHWRender::MTexture* fUVEditorTexture; 511 | 512 | #ifdef USE_GL_TEXTURE_CACHING 513 | // Caching for UV Texture image 514 | MString fUVEditorLastTexture; 515 | MString fUVEditorLastLayer; 516 | int fUVEditorLastAlphaChannel; 517 | float fUVEditorBaseColor[4]; 518 | bool fUVEditorShowAlphaMask; 519 | unsigned int fUVEditorGLTextureId; 520 | float fUVEditorGLTextureScaleU; 521 | float fUVEditorGLTextureScaleV; 522 | #endif //USE_GL_TEXTURE_CACHING 523 | 524 | // Bounding Box Extra Scale 525 | MString fBBoxExtraScalePlugName; 526 | double fBBoxExtraScaleValue; 527 | 528 | // Maya Swatch Render 529 | dx11ShaderDX11EffectVariable* fMayaSwatchRenderVar; 530 | 531 | // Maya full screen gamma correction 532 | dx11ShaderDX11EffectVariable* fMayaGammaCorrectVar; 533 | 534 | ///////////// Some caching 535 | typedef std::map< dx11ShaderDX11Pass*, bool > PassHasHullShaderMap; 536 | mutable PassHasHullShaderMap fPassHasHullShaderMap; 537 | 538 | struct CachedInputElementDesc 539 | { 540 | MString SemanticName; 541 | unsigned int SemanticIndex; 542 | int Format; 543 | unsigned int InputSlot; 544 | unsigned int AlignedByteOffset; 545 | int InputSlotClass; 546 | unsigned int InstanceDataStepRate; 547 | }; 548 | 549 | struct InputLayoutData 550 | { 551 | dx11ShaderDX11InputLayout* inputLayout; 552 | unsigned int numLayouts; 553 | CachedInputElementDesc* layoutDesc; 554 | }; 555 | typedef std::map< dx11ShaderDX11Pass*, InputLayoutData > PassInputLayoutMap; 556 | mutable PassInputLayoutMap fPassInputLayoutMap; 557 | 558 | ///////////// Diagnostics/description strings 559 | mutable MString fErrorLog; 560 | mutable MString fWarningLog; 561 | mutable unsigned int fErrorCount; 562 | }; 563 | 564 | 565 | // INLINE 566 | 567 | ///////////////////////////////// 568 | // Topology Management 569 | inline bool dx11ShaderNode::rebuildAlways(size_t baseVersionId) const 570 | { 571 | return hasUpdatedVaryingInput() || isDirty(baseVersionId); 572 | } 573 | 574 | inline bool dx11ShaderNode::isDirty(size_t baseVersionId) const 575 | { 576 | return (fGeometryVersionId != baseVersionId); 577 | } 578 | 579 | inline size_t dx11ShaderNode::geometryVersionId() const 580 | { 581 | return fGeometryVersionId; 582 | } 583 | 584 | ///////////////////////////////// 585 | // Effect Management 586 | inline const MString& dx11ShaderNode::effectName() const 587 | { 588 | return fEffectName; 589 | } 590 | 591 | inline dx11ShaderDX11Effect* dx11ShaderNode::effect() const 592 | { 593 | return fEffect; 594 | } 595 | 596 | inline double dx11ShaderNode::boundingBoxExtraScale() const 597 | { 598 | return (fBBoxExtraScaleValue > 1.0f ? fBBoxExtraScaleValue : 1.0f); 599 | } 600 | 601 | ///////////////////////////////// 602 | // Technique Management 603 | inline const MStringArray& dx11ShaderNode::techniques() const 604 | { 605 | return fTechniqueNames; 606 | } 607 | 608 | inline int dx11ShaderNode::techniqueCount() const 609 | { 610 | return (int)fTechniqueNames.length(); 611 | } 612 | 613 | inline int dx11ShaderNode::activeTechnique() const 614 | { 615 | return fTechniqueIdx; 616 | } 617 | 618 | inline dx11ShaderDX11EffectTechnique* dx11ShaderNode::technique() const 619 | { 620 | return fTechnique; 621 | } 622 | 623 | inline const MString& dx11ShaderNode::activeTechniqueName() const 624 | { 625 | return fTechniqueName; 626 | } 627 | 628 | inline const MString& dx11ShaderNode::techniqueIndexBufferType() const 629 | { 630 | return fTechniqueIndexBufferType; 631 | } 632 | 633 | inline bool dx11ShaderNode::techniqueOverridesDrawState() const 634 | { 635 | return fTechniqueOverridesDrawState; 636 | } 637 | 638 | ///////////////////////////////// 639 | // Pass Management 640 | inline int dx11ShaderNode::passCount() const 641 | { 642 | return fPassCount; 643 | } 644 | 645 | ///////////////////////////////// 646 | // Attibute Editor 647 | inline const MStringArray& dx11ShaderNode::getUIGroups() const 648 | { 649 | return fUIGroupNames; 650 | } 651 | 652 | inline const MStringArray& dx11ShaderNode::lightInfoDescription() const 653 | { 654 | return fLightDescriptions; 655 | } 656 | 657 | #endif /* _dx11ShaderNode_h_ */ 658 | 659 | -------------------------------------------------------------------------------- /dx11Shader.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2012 3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx11Shader", "dx11Shader.vcxproj", "{2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|x64 = Debug|x64 8 | Hybrid|x64 = Hybrid|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Debug|x64.ActiveCfg = Debug|x64 13 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Debug|x64.Build.0 = Debug|x64 14 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Hybrid|x64.ActiveCfg = Hybrid|x64 15 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Hybrid|x64.Build.0 = Hybrid|x64 16 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Release|x64.ActiveCfg = Release|x64 17 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /dx11Shader.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Hybrid 10 | x64 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | {2F72A8B3-E1FD-4834-AD56-0B16F850C2FB} 19 | dx11Shader 20 | 21 | 22 | 23 | DynamicLibrary 24 | v110 25 | 26 | 27 | DynamicLibrary 28 | v110 29 | 30 | 31 | DynamicLibrary 32 | v110 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | <_ProjectFileVersion>10.0.40219.1 52 | $(Platform)\$(Configuration)\ 53 | $(Platform)\$(Configuration)\ 54 | $(Platform)\$(Configuration)\ 55 | $(Platform)\$(Configuration)\ 56 | $(Platform)\$(Configuration)\ 57 | $(Platform)\$(Configuration)\ 58 | .mll 59 | .mll 60 | .mll 61 | 62 | 63 | $(WindowsSDK_IncludePath);C:\Program Files\Autodesk\Maya2015\include;$(IncludePath) 64 | $(WindowsSDK_LibraryPath_x64);C:\Program Files\Autodesk\Maya2015\lib;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64;$(LibraryPath) 65 | 66 | 67 | $(WindowsSDK_IncludePath);C:\Program Files\Autodesk\Maya2015\include;$(IncludePath) 68 | $(WindowsSDK_LibraryPath_x64);C:\Program Files\Autodesk\Maya2015\lib;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64;$(LibraryPath) 69 | 70 | 71 | $(WindowsSDK_IncludePath);C:\Program Files\Autodesk\Maya2015\include;$(IncludePath) 72 | $(WindowsSDK_LibraryPath_x64);C:\Program Files\Autodesk\Maya2015\lib;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64;$(LibraryPath) 73 | 74 | 75 | 76 | X64 77 | 78 | 79 | /I "." /c %(AdditionalOptions) 80 | Disabled 81 | %(AdditionalIncludeDirectories) 82 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;D3D9_SUPPORTED;D3D_DEBUG_INFO;%(PreprocessorDefinitions) 83 | MultiThreadedDebugDLL 84 | $(Platform)\$(Configuration)\dx11Shader.pch 85 | Level3 86 | EnableFastChecks 87 | true 88 | ProgramDatabase 89 | false 90 | 91 | 92 | /export:initializePlugin /export:uninitializePlugin /LTCG %(AdditionalOptions) 93 | Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenMayaFX.lib;OpenMayaRender.lib;OpenMayaAnim.lib;Image.lib;d3d11.lib;d3dx11.lib;dxguid.lib;glu32.lib;opengl32.lib;D3DX11EffectsD.lib;d3dcompiler.lib;%(AdditionalDependencies) 94 | $(OutDir)$(TargetName)$(TargetExt) 95 | %(AdditionalLibraryDirectories);. 96 | $(Platform)\$(Configuration)\dx11Shader.pdb 97 | $(Platform)\$(Configuration)\dx11Shader.lib 98 | MachineX64 99 | Windows 100 | true 101 | 102 | 103 | 104 | 105 | X64 106 | 107 | 108 | /I "." /c %(AdditionalOptions) 109 | Disabled 110 | %(AdditionalIncludeDirectories) 111 | _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;D3D9_SUPPORTED;D3D_DEBUG_INFO;%(PreprocessorDefinitions) 112 | MultiThreadedDLL 113 | $(Platform)\$(Configuration)\dx11Shader.pch 114 | Level3 115 | EnableFastChecks 116 | false 117 | ProgramDatabase 118 | false 119 | 120 | 121 | /export:initializePlugin /export:uninitializePlugin /LTCG %(AdditionalOptions) 122 | Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenMayaFX.lib;OpenMayaRender.lib;OpenMayaAnim.lib;Image.lib;d3d11.lib;d3dx11.lib;dxguid.lib;glu32.lib;opengl32.lib;D3DX11Effects.lib;d3dcompiler.lib;%(AdditionalDependencies) 123 | $(OutDir)$(TargetName)$(TargetExt) 124 | %(AdditionalLibraryDirectories);. 125 | $(Platform)\$(Configuration)\dx11Shader.pdb 126 | $(Platform)\$(Configuration)\dx11Shader.lib 127 | MachineX64 128 | Windows 129 | true 130 | 131 | 132 | 133 | 134 | X64 135 | 136 | 137 | /I "." /c %(AdditionalOptions) 138 | MaxSpeed 139 | %(AdditionalIncludeDirectories) 140 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;D3D9_SUPPORTED;%(PreprocessorDefinitions) 141 | MultiThreadedDLL 142 | $(Platform)\$(Configuration)\dx11Shader.pch 143 | Level3 144 | NotUsing 145 | 146 | 147 | /export:initializePlugin /export:uninitializePlugin /LTCG %(AdditionalOptions) 148 | Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenMayaFX.lib;OpenMayaRender.lib;OpenMayaAnim.lib;Image.lib;d3d11.lib;d3dx11.lib;dxguid.lib;glu32.lib;opengl32.lib;D3DX11Effects.lib;d3dcompiler.lib;%(AdditionalDependencies) 149 | $(OutDir)$(TargetName)$(TargetExt) 150 | %(AdditionalLibraryDirectories);. 151 | true 152 | $(Platform)\$(Configuration)\dx11Shader.pdb 153 | $(Platform)\$(Configuration)\dx11Shader.lib 154 | MachineX64 155 | Windows 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /dx11ShaderCmd.cpp: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved. 3 | // 4 | // Use of this software is subject to the terms of the Autodesk 5 | // license agreement provided at the time of installation or download, 6 | // or which otherwise accompanies this software in either electronic 7 | // or hard copy form. 8 | // ========================================================================== 9 | //+ 10 | 11 | #if _MSC_VER >= 1700 12 | #pragma warning( disable: 4005 ) 13 | #endif 14 | 15 | #include "dx11ShaderCmd.h" 16 | #include "dx11Shader.h" 17 | #include "dx11ShaderStrings.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | // hlslShaderCmd 29 | // 30 | 31 | // Forces all dx11Shader nodes that share the same effect name to reload the effect. 32 | #define kReloadFlag "-r" 33 | #define kReloadFlagLong "-reload" 34 | 35 | // Retrives the effect file name. Functionnally equivalent to "getAttr dx11Shader1.shader" 36 | // 37 | // example: 38 | // dx11Shader dx11Shader1 -q -fx; 39 | // Result: MayaUberShader.fxo // 40 | #define kFXFileFlag "-fx" 41 | #define kFXFileFlagLong "-fxFile" 42 | 43 | // Retrieves a string array containing all techniques supported by the shader 44 | // 45 | // example: 46 | // dx11Shader dx11Shader1 -q -lt; 47 | // Result: TessellationOFF TessellationON WireFrame // 48 | #define kListTechniquesFlag "-lt" 49 | #define kListTechniquesFlagLong "-listTechniques" 50 | 51 | // Clears all parameters of the dx11Shader node 52 | #define kClearParametersFlag "-c" 53 | #define kClearParametersFlagLong "-clearParameters" 54 | 55 | // Returns a string array containing a pair (Light Group Name, Light Group Type) for 56 | // all logical light groups found in the effect 57 | // 58 | // example: 59 | // dx11Shader dx11Shader1 -q -li; 60 | // Result: Light 0 undefined Light 1 undefined Light 2 undefined // 61 | #define kListLightInformationFlag "-li" 62 | #define kListLightInformationFlagLong "-listLightInformation" 63 | 64 | // Lists all the parameter names that are member of a logical light. The 65 | // light group name must be provided: 66 | // 67 | // example: 68 | // dx11Shader dx11Shader1 -lp "Light 0"; 69 | // Result: Enable_Light_0 Light_0_Position Light_0_Color Light_0_Intensity... 70 | #define kListLightParametersFlag "-lp" 71 | #define kListLightParametersFlagLong "-listLightParameters" 72 | 73 | // Used together with the -listLightParameters flag, this returns the semantics 74 | // of each light parameter: 75 | // 76 | // example: 77 | // dx11Shader dx11Shader1 -lp "Light 0" -sem; 78 | // Result: Enable_Light_0 LightEnable Light_0_Position Position Light_0_Color LightColor... 79 | #define kListLightParameterSemanticsFlag "-sem" 80 | #define kListLightParameterSemanticsFlagLong "-semantics" 81 | 82 | // List all UI groups names: 83 | // 84 | // example: 85 | // dx11Shader dx11Shader1 -q -lg; 86 | // Result: Lighting Light 0 Light 1 Light 2 Ambient and Emissive Diffuse Opacity... 87 | #define kListUIGroupInformationFlag "-lg" 88 | #define kListUIGroupInformationFlagLong "-listUIGroupInformation" 89 | 90 | // Lists all the parameter names that are member of a UI group. The 91 | // group name must be provided: 92 | // 93 | // example: 94 | // dx11Shader dx11Shader1 -lgp "Diffuse"; 95 | // Result: Diffuse_Map Diffuse_Map_Alpha Diffuse_Map_1 Diffuse_Color Lightmap_Map... 96 | #define kListUIGroupParametersFlag "-lgp" 97 | #define kListUIGroupParametersFlagLong "-listUIGroupParameters" 98 | 99 | // Connects a scene light to a logical light: 100 | // 101 | // example: 102 | // dx11Shader dx11Shader1 -cl Light_0 pointLight1; 103 | #define kConnectLightFlag "-cl" 104 | #define kConnectLightFlagLong "-connectLight" 105 | 106 | // Returns the scene light that is currently driving a light group: 107 | // 108 | // example: 109 | // dx11Shader dx11Shader1 -lcs Light_0; 110 | // Result: pointLight1 111 | // dx11Shader dx11Shader1 -lcs Light_1; 112 | // 113 | #define kLightConnectionStatusFlag "-lcs" 114 | #define kLightConnectionStatusFlagLong "-lightConnectionStatus" 115 | 116 | // Explicitly disconnect a scene light from a light group. This will put the 117 | // light into the "Use Shader Settings" mode. To go back to "Automatic Bind", 118 | // you must also set the value of the implicit bind attribute: 119 | // 120 | // example: 121 | // dx11Shader dx11Shader1 -d Light_0; 122 | // setAttr dx11Shader1.Light_0_use_implicit_lighting 1; 123 | #define kDisconnectLightFlag "-d" 124 | #define kDisconnectLightFlagLong "-disconnectLight" 125 | 126 | 127 | 128 | dx11ShaderCmd::dx11ShaderCmd() 129 | {} 130 | 131 | dx11ShaderCmd::~dx11ShaderCmd() 132 | {} 133 | 134 | MStatus dx11ShaderCmd::doIt( const MArgList& args ) 135 | { 136 | MStatus status; 137 | 138 | // Parse the shader node 139 | // 140 | MArgParser parser( syntax(), args ); 141 | MString nodeName; 142 | parser.getCommandArgument( 0, nodeName ); 143 | 144 | 145 | MSelectionList list; 146 | status = list.add( nodeName ); 147 | MObject shaderNode; 148 | status = list.getDependNode( 0, shaderNode ); 149 | if( status != MS::kSuccess ) 150 | { 151 | MStringArray args; 152 | args.append(nodeName); 153 | 154 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kInvalidDx11ShaderNode, args ); 155 | displayError( msg ); 156 | return MS::kFailure; 157 | } 158 | 159 | MArgDatabase argData( syntax(), args, &status ); 160 | if ( !status ) 161 | return status; 162 | 163 | bool fIsQuery = argData.isQuery(); 164 | 165 | MFnDependencyNode depFn( shaderNode ); 166 | if( depFn.typeId() != dx11ShaderNode::typeId() ) 167 | { 168 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kInvalidDx11ShaderNode, nodeName ); 169 | displayError( msg ); 170 | return MS::kFailure; 171 | } 172 | 173 | dx11ShaderNode* shader = (dx11ShaderNode*) depFn.userNode(); 174 | if( !shader ) 175 | { 176 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kInvalidDx11ShaderNode, nodeName ); 177 | displayError( msg ); 178 | return MS::kFailure; 179 | } 180 | 181 | if ( fIsQuery ) 182 | { 183 | if( parser.isFlagSet(kFXFileFlag) ) 184 | { 185 | MString path = shader->effectName(); 186 | setResult( path ); 187 | return MS::kSuccess; 188 | } 189 | else if( parser.isFlagSet( kListTechniquesFlag ) ) 190 | { 191 | setResult( shader->techniques() ); 192 | return MS::kSuccess; 193 | } 194 | else if( parser.isFlagSet( kListLightInformationFlag ) ) 195 | { 196 | setResult( shader->lightInfoDescription() ); 197 | return MS::kSuccess; 198 | } 199 | else if( parser.isFlagSet( kListUIGroupInformationFlag ) ) 200 | { 201 | setResult( shader->getUIGroups() ); 202 | return MS::kSuccess; 203 | } 204 | } 205 | else 206 | { 207 | // Process flag arguments 208 | // 209 | if( parser.isFlagSet(kReloadFlag) ) 210 | { 211 | dx11ShaderNode::reloadAll( shader->effectName() ); 212 | //shader->reload( ); 213 | } 214 | else if( parser.isFlagSet(kClearParametersFlag)) 215 | { 216 | shader->clearParameters(); 217 | } 218 | else if( parser.isFlagSet(kConnectLightFlag)) 219 | { 220 | MString connectableLightName; 221 | argData.getFlagArgument(kConnectLightFlag, 0, connectableLightName); 222 | int lightIndex = shader->getIndexForLightName(connectableLightName); 223 | if (lightIndex < 0) 224 | { 225 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownConnectableLight, connectableLightName ); 226 | displayError( msg ); 227 | return MS::kFailure; 228 | } 229 | MString lightName; 230 | argData.getFlagArgument(kConnectLightFlag, 1, lightName); 231 | MDagPath lightPath; 232 | list.clear(); 233 | list.add( lightName ); 234 | status = list.getDagPath(0, lightPath); 235 | if( status != MS::kSuccess ) 236 | { 237 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownSceneObject, lightName ); 238 | displayError( msg ); 239 | return MS::kFailure; 240 | } 241 | // Make sure it is a light: 242 | MDagPath lightShapeDagPath; 243 | unsigned int numShapes = 0; 244 | lightPath.numberOfShapesDirectlyBelow(numShapes); 245 | for (unsigned int i = 0; i < numShapes; ++i) 246 | { 247 | MDagPath shapePath(lightPath); 248 | status = shapePath.extendToShapeDirectlyBelow(i); 249 | if( status == MS::kSuccess && shapePath.hasFn(MFn::kLight)) 250 | { 251 | lightShapeDagPath = shapePath; 252 | break; 253 | } 254 | } 255 | 256 | if (!lightShapeDagPath.isValid()) 257 | { 258 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kNotALight, lightName ); 259 | displayError( msg ); 260 | return MS::kFailure; 261 | } 262 | 263 | shader->disconnectLight(lightIndex); 264 | shader->connectLight(lightIndex,lightShapeDagPath); 265 | return MS::kSuccess; 266 | } 267 | else if( parser.isFlagSet(kLightConnectionStatusFlag)) 268 | { 269 | MString connectableLightName; 270 | argData.getFlagArgument(kLightConnectionStatusFlag, 0, connectableLightName); 271 | int lightIndex = shader->getIndexForLightName(connectableLightName); 272 | if (lightIndex < 0) 273 | { 274 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownConnectableLight, connectableLightName ); 275 | displayError( msg ); 276 | return MS::kFailure; 277 | } 278 | setResult( shader->getLightConnectionInfo(lightIndex)); 279 | return MS::kSuccess; 280 | } 281 | else if(parser.isFlagSet(kListLightParametersFlag)) 282 | { 283 | MString connectableLightName; 284 | argData.getFlagArgument(kListLightParametersFlag, 0, connectableLightName); 285 | int lightIndex = shader->getIndexForLightName(connectableLightName); 286 | if (lightIndex < 0) 287 | { 288 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownConnectableLight, connectableLightName ); 289 | displayError( msg ); 290 | return MS::kFailure; 291 | } 292 | setResult( shader->getLightableParameters(lightIndex, parser.isFlagSet(kListLightParameterSemanticsFlag) )); 293 | return MS::kSuccess; 294 | } 295 | else if(parser.isFlagSet(kListUIGroupParametersFlag)) 296 | { 297 | MString connectableUIGroupName; 298 | argData.getFlagArgument(kListUIGroupParametersFlag, 0, connectableUIGroupName); 299 | int uiGroupIndex = shader->getIndexForUIGroupName(connectableUIGroupName); 300 | if (uiGroupIndex < 0) 301 | { 302 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownUIGroup, connectableUIGroupName ); 303 | displayError( msg ); 304 | return MS::kFailure; 305 | } 306 | setResult( shader->getUIGroupParameters(uiGroupIndex) ); 307 | return MS::kSuccess; 308 | } 309 | else if( parser.isFlagSet(kDisconnectLightFlag)) 310 | { 311 | MString lightName; 312 | argData.getFlagArgument(kDisconnectLightFlag, 0, lightName); 313 | int lightIndex = shader->getIndexForLightName(lightName); 314 | if (lightIndex < 0) 315 | { 316 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kUnknownConnectableLight, lightName ); 317 | displayError( msg ); 318 | return MS::kFailure; 319 | } 320 | shader->disconnectLight(lightIndex); 321 | return MS::kSuccess; 322 | } 323 | } 324 | 325 | 326 | return MS::kSuccess; 327 | } 328 | 329 | MSyntax dx11ShaderCmd::newSyntax() 330 | { 331 | MSyntax syntax; 332 | syntax.enableQuery(); 333 | syntax.addFlag( kReloadFlag, kReloadFlagLong); 334 | syntax.addFlag( kFXFileFlag, kFXFileFlagLong, MSyntax::kString ); 335 | syntax.addFlag( kListTechniquesFlag, kListTechniquesFlagLong); 336 | syntax.addFlag( kClearParametersFlag, kClearParametersFlagLong); 337 | syntax.addFlag( kListLightInformationFlag, kListLightInformationFlagLong); 338 | syntax.addFlag( kConnectLightFlag, kConnectLightFlagLong, MSyntax::kString, MSyntax::kString ); 339 | syntax.addFlag( kLightConnectionStatusFlag, kLightConnectionStatusFlagLong, MSyntax::kString ); 340 | syntax.addFlag( kListLightParametersFlag, kListLightParametersFlagLong, MSyntax::kString ); 341 | syntax.addFlag( kListLightParameterSemanticsFlag, kListLightParameterSemanticsFlagLong ); 342 | syntax.addFlag( kListUIGroupInformationFlag, kListUIGroupInformationFlagLong); 343 | syntax.addFlag( kListUIGroupParametersFlag, kListUIGroupParametersFlagLong, MSyntax::kString ); 344 | syntax.addFlag( kDisconnectLightFlag, kDisconnectLightFlagLong, MSyntax::kString); 345 | syntax.addArg( MSyntax::kString ); 346 | return syntax; 347 | } 348 | 349 | void* dx11ShaderCmd::creator() 350 | { 351 | return new dx11ShaderCmd; 352 | } 353 | 354 | -------------------------------------------------------------------------------- /dx11ShaderCmd.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ShaderCmd_h_ 2 | #define _dx11ShaderCmd_h_ 3 | //- 4 | // ========================================================================== 5 | // Copyright 1995,2006,2008,2011 Autodesk, Inc. All rights reserved. 6 | // 7 | // Use of this software is subject to the terms of the Autodesk 8 | // license agreement provided at the time of installation or download, 9 | // or which otherwise accompanies this software in either electronic 10 | // or hard copy form. 11 | // ========================================================================== 12 | //+ 13 | 14 | #include 15 | #include 16 | 17 | class dx11ShaderCmd : MPxCommand 18 | { 19 | public: 20 | dx11ShaderCmd(); 21 | virtual ~dx11ShaderCmd(); 22 | 23 | MStatus doIt( const MArgList& ); 24 | bool isUndoable() { return false; } 25 | 26 | static MSyntax newSyntax(); 27 | static void* creator(); 28 | }; 29 | 30 | #endif /* _dx11ShaderCmd_h_ */ -------------------------------------------------------------------------------- /dx11ShaderCompileHelper.cpp: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved. 3 | // 4 | // Use of this software is subject to the terms of the Autodesk 5 | // license agreement provided at the time of installation or download, 6 | // or which otherwise accompanies this software in either electronic 7 | // or hard copy form. 8 | // ========================================================================== 9 | //+ 10 | 11 | #if _MSC_VER >= 1700 12 | #pragma warning( disable: 4005 ) 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "dx11ShaderCompileHelper.h" 21 | #include "dx11ShaderStrings.h" 22 | 23 | // Includes for DX11 24 | #define WIN32_LEAN_AND_MEAN 25 | #include 26 | #if _MSC_VER < 1700 27 | #include 28 | #endif 29 | 30 | // To build against the DX SDK header use the following commented line 31 | //#include <../Samples/C++/Effects11/Inc/d3dx11effect.h> 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | /*! 42 | CDX11EffectCompileHelper::EffectCollection 43 | Is a collection of the all effects currently used by the scene. 44 | When a .fx file is loaded, a look up is done in the collection for a compiled version, 45 | if found it will be cloned and added to the collection. 46 | It has to be cloned because each effect need to have distinct parameters. 47 | 48 | CDX11EffectCompileHelper::CompiledEffectCache 49 | Is a simple LRU for the last 8 compiled effects. 50 | Since the collection above is only used to store the effects currently active in the scene, 51 | this LRU is used to prevent reloading over and over the MayaUberShader which is assigned by default on each new dx11Shader. 52 | 2 callbacks are registered to flush the LRU when the scene is closed and when maya is about to close: 53 | MsceneMessage::addCallback(MSceneMessage::kMayaExiting) 54 | MsceneMessage::addCallback(MSceneMessage::kBeforeNew) 55 | */ 56 | 57 | namespace CDX11EffectCompileHelper 58 | { 59 | class CFileReferenceHelper 60 | { 61 | public: 62 | MString resolveFileName(const char* fileName) const; 63 | void setReferencePath(MString fileName); 64 | 65 | protected: 66 | MString findFile(const char* fileName) const; 67 | MString getSearchPaths() const; 68 | 69 | MString referencePath; 70 | }; 71 | 72 | MString CFileReferenceHelper::resolveFileName(const char* fileName) const 73 | { 74 | //Check if filename exists 75 | MString currFileName(fileName); 76 | MString file = findFile(currFileName.asChar()); 77 | 78 | int hasFile = file.length() > 0; 79 | 80 | if (hasFile == 0) 81 | { 82 | // lets extract the filename and try it again... 83 | int idx = currFileName.rindex('/'); 84 | if (idx == -1) 85 | idx = currFileName.rindex('\\'); 86 | if (idx != -1) 87 | { 88 | currFileName = currFileName.substring(idx+1,currFileName.length()-1); 89 | file = findFile(currFileName.asChar()); 90 | } 91 | } 92 | 93 | if (file.length() == 0) 94 | { 95 | MString expandedFileName(MString(fileName).expandEnvironmentVariablesAndTilde()); 96 | file = findFile(expandedFileName.asChar()); 97 | } 98 | 99 | return file; 100 | } 101 | 102 | void CFileReferenceHelper::setReferencePath(MString fileName) 103 | { 104 | referencePath.clear(); 105 | // split file path in filename path 106 | // lets extract the filename and try it again... 107 | int idx = fileName.rindex('/'); 108 | if (idx == -1) 109 | idx = fileName.rindex('\\'); 110 | if (idx != -1) 111 | { 112 | referencePath = fileName.substring(0,idx); 113 | } 114 | } 115 | 116 | MString CFileReferenceHelper::findFile(const char* fileName) const 117 | { 118 | struct stat statBuf; 119 | MString name (fileName); 120 | const bool fullyQualified = name.index('/') == 0 || name.index('\\') == 0 || name.index(':') == 1; 121 | if (fullyQualified && stat(name.asChar(), &statBuf) != -1) 122 | { 123 | return name; 124 | } 125 | 126 | char path[MAX_PATH]; 127 | MString searchPaths = getSearchPaths(); 128 | const char * psearchpath = searchPaths.asChar(); 129 | 130 | /// Strip out any leading '/' at this point since the file has 131 | // not been found using a fully qualified path. 132 | MString resolvedName; 133 | if(name.index('/') == 0 || name.index('\\') == 0) 134 | resolvedName = name.substring(1, name.length() - 1); 135 | else 136 | resolvedName = name; 137 | 138 | while (psearchpath < searchPaths.asChar() + searchPaths.length()) 139 | { 140 | const char * endpath = strchr(psearchpath,';'); 141 | if (endpath) 142 | { 143 | strncpy(path,psearchpath, endpath - psearchpath); 144 | path[endpath - psearchpath] = '\0'; 145 | } 146 | else 147 | { 148 | strcpy(path,psearchpath); 149 | } 150 | 151 | psearchpath += strlen(path)+1; 152 | 153 | bool fullPath = (path[0] == '/' || path[0] == '\\'); 154 | 155 | if (strlen(path) > 2) 156 | { 157 | fullPath = fullPath || 158 | (path[1] == ':' && 159 | (path[2] == '/' || 160 | path[2] == '\\')); 161 | } 162 | 163 | // Add the path and the filename together to get the full path 164 | MString file; 165 | if(path[strlen(path) - 1] != '/') 166 | file = MString(path) + "/" + resolvedName; 167 | else 168 | file = MString(path) + resolvedName; 169 | 170 | 171 | if (stat(file.asChar(), &statBuf) != -1) 172 | { 173 | return file; 174 | } 175 | } 176 | return MString(); 177 | } 178 | 179 | MString CFileReferenceHelper::getSearchPaths() const 180 | { 181 | // Build a list of places we'll look for textures 182 | MString searchPaths; 183 | 184 | // Add the standard Maya project paths 185 | MString workspace; 186 | MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"),workspace); 187 | if ( status == MS::kSuccess) 188 | { 189 | searchPaths += workspace; 190 | searchPaths += ";"; 191 | searchPaths += workspace; 192 | searchPaths += "/renderData/shaders"; 193 | MString shadersRelativePath; 194 | status = MGlobal::executeCommand(MString("workspace -fre shaders"),shadersRelativePath); 195 | if(status== MS::kSuccess) 196 | { 197 | searchPaths += ";"; 198 | searchPaths += workspace; 199 | searchPaths += shadersRelativePath; 200 | } 201 | } 202 | 203 | if(referencePath.length() > 0) 204 | { 205 | if(searchPaths.length() > 0) 206 | { 207 | searchPaths += ";"; 208 | } 209 | searchPaths += referencePath; 210 | } 211 | 212 | static char * dx11ShaderRoot = getenv("DX11SHADER_ROOT"); 213 | if (dx11ShaderRoot) 214 | { 215 | if(searchPaths.length() > 0) 216 | { 217 | searchPaths += ";"; 218 | } 219 | searchPaths += dx11ShaderRoot; 220 | searchPaths += ";"; 221 | searchPaths += dx11ShaderRoot; 222 | searchPaths += "/shaders"; 223 | } 224 | 225 | searchPaths += ";"; 226 | searchPaths += MString("${MAYA_LOCATION}/presets/HLSL11/examples").expandEnvironmentVariablesAndTilde(); 227 | 228 | return searchPaths; 229 | } 230 | 231 | //////////////////////////////////////////////////////////////////////////////////////////////////// 232 | 233 | class CIncludeHelper: public ID3D10Include, public CFileReferenceHelper 234 | { 235 | public: 236 | STDMETHOD(Open)(D3D10_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) 237 | { 238 | MString resolvedFileName = resolveFileName(pFileName); 239 | // Read the file content 240 | FILE* file = fopen(resolvedFileName.asChar(), "rb"); 241 | if(file == NULL) 242 | { 243 | return E_FAIL; 244 | } 245 | 246 | // Get the file size 247 | fseek(file, 0, SEEK_END); 248 | long size = ftell(file); 249 | fseek(file, 0, SEEK_SET); 250 | 251 | // Get the file content 252 | char *buffer = new char[size]; 253 | fread(buffer, 1, size, file); 254 | fclose(file); 255 | 256 | // Save the file data into ppData and the size into pBytes. 257 | *ppData = buffer; 258 | *pBytes = UINT(size); 259 | 260 | return S_OK; 261 | } 262 | STDMETHOD(Close)(LPCVOID pData) 263 | { 264 | char* pChar = (char*)pData; 265 | delete [] pChar; 266 | return S_OK; 267 | } 268 | }; 269 | 270 | //////////////////////////////////////////////////////////////////////////////////////////////////// 271 | 272 | D3D10_SHADER_MACRO* getD3DMacros() 273 | { 274 | static D3D10_SHADER_MACRO macros[] = { { "DIRECT3D_VERSION", "0xb00" }, 275 | { "_MAYA_", "1"}, // similar to _3DSMAX_ and _XSI_ macros for other 3d apps 276 | { "MAYA_DX11", "1"}, 277 | { NULL, NULL } }; 278 | return macros; 279 | } 280 | 281 | unsigned int getShaderCompileFlags(bool useStrictness) 282 | { 283 | unsigned int flags = 0; 284 | 285 | #ifdef _DEBUG 286 | // Optionally enable debugging information to be stored, without reducing performance. 287 | flags |= D3DCOMPILE_DEBUG; 288 | flags |= D3DCOMPILE_SKIP_OPTIMIZATION; 289 | #endif 290 | 291 | if(useStrictness) 292 | { 293 | // Enable strictness 294 | flags |= D3DCOMPILE_ENABLE_STRICTNESS; 295 | } 296 | else 297 | { 298 | // Allow for backwards compatibility 299 | flags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; 300 | } 301 | 302 | return flags; 303 | } 304 | 305 | bool effectHasHullShader(ID3DX11Effect* effect) 306 | { 307 | if(effect) 308 | { 309 | D3DX11_EFFECT_DESC effectDesc; 310 | effect->GetDesc(&effectDesc); 311 | for(unsigned int i = 0; i < effectDesc.Techniques; ++i) 312 | { 313 | ID3DX11EffectTechnique* technique = effect->GetTechniqueByIndex(i); 314 | if(technique && technique->IsValid()) 315 | { 316 | D3DX11_TECHNIQUE_DESC techniqueDesc; 317 | technique->GetDesc(&techniqueDesc); 318 | for(unsigned int j = 0;j < techniqueDesc.Passes;++j) 319 | { 320 | ID3DX11EffectPass* pass = technique->GetPassByIndex(j); 321 | if(pass && pass->IsValid()) 322 | { 323 | D3DX11_PASS_SHADER_DESC shaderDesc; 324 | HRESULT hr = pass->GetHullShaderDesc(&shaderDesc); 325 | if(hr == S_OK && shaderDesc.pShaderVariable && shaderDesc.pShaderVariable->IsValid()) 326 | { 327 | ID3D11HullShader* pHullShader = NULL; 328 | shaderDesc.pShaderVariable->GetHullShader(shaderDesc.ShaderIndex,&pHullShader); 329 | if(pHullShader) 330 | { 331 | //Found a hull shader 332 | pHullShader->Release(); 333 | return true; 334 | } 335 | 336 | } 337 | } 338 | } 339 | } 340 | } 341 | 342 | } 343 | return false; 344 | } 345 | 346 | bool isValidEffectFile(const MString& fileName, bool& isCompiled) 347 | { 348 | MString extension; 349 | 350 | int idx = fileName.rindexW(L'.'); 351 | if(idx > 0) 352 | { 353 | extension = fileName.substringW( idx+1, fileName.length()-1 ); 354 | extension = extension.toLowerCase(); 355 | } 356 | 357 | isCompiled = (extension == "fxo"); 358 | return (extension == "fx" || extension == "fxo"); 359 | } 360 | 361 | void pushError(const MString& fileName, MString &errorLog, ID3DBlob* error) 362 | { 363 | char* pMessage = (error && error->GetBufferSize() > 0) ? (char*) error->GetBufferPointer() : NULL; 364 | 365 | MStringArray args; 366 | args.append(fileName); 367 | args.append(MString(pMessage)); 368 | 369 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorEffectCompile, args ); 370 | errorLog += msg; 371 | } 372 | 373 | void pushError(MString &errorLog, ID3DBlob* error) 374 | { 375 | char* pMessage = (error && error->GetBufferSize() > 0) ? (char*) error->GetBufferPointer() : NULL; 376 | 377 | MStringArray args; 378 | args.append(MString(pMessage)); 379 | 380 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorEffectBuffer, args ); 381 | errorLog += msg; 382 | } 383 | 384 | //////////////////////////////////////////////////////////////////////////////////////////////////// 385 | 386 | time_t fileTimeStamp(const MString& fileName) 387 | { 388 | struct stat statBuf; 389 | if( stat(fileName.asChar(), &statBuf) != 0 ) 390 | return 0; 391 | 392 | return statBuf.st_mtime; 393 | } 394 | 395 | struct EffectKey 396 | { 397 | ID3D11Device* device; 398 | MString fileName; 399 | time_t timeStamp; 400 | }; 401 | 402 | bool operator< (const EffectKey& lhs, const EffectKey& rhs) 403 | { 404 | return (lhs.device < rhs.device) || 405 | (lhs.device == rhs.device && ( (lhs.timeStamp < rhs.timeStamp) || 406 | (lhs.timeStamp == rhs.timeStamp && strcmp(lhs.fileName.asChar(), rhs.fileName.asChar()) < 0) ) ); 407 | } 408 | 409 | struct MStringSorter { 410 | bool operator() (const MString& lhs, const MString& rhs) const 411 | { 412 | return strcmp(lhs.asChar(), rhs.asChar()) < 0; 413 | } 414 | }; 415 | 416 | class EffectCollection 417 | { 418 | public: 419 | ID3DX11Effect* acquire(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName); 420 | ID3DX11Effect* acquire(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, ID3DX11Effect* reference, ID3DX11Effect* source = NULL); 421 | void release(dx11ShaderNode* node, ID3DX11Effect *effect, const MString& fileName); 422 | void getNodesUsingEffect(const MString& fileName, ShaderNodeList &nodes) const; 423 | 424 | ID3DX11Effect* getReferenceEffectAndFileName(ID3DX11Effect *effect, MString& fileName) const; 425 | 426 | private: 427 | typedef std::map< EffectKey, ID3DX11Effect* > Key2ReferenceEffectMap; 428 | Key2ReferenceEffectMap key2ReferenceEffectMap; 429 | 430 | typedef std::pair< EffectKey, unsigned int > EffectKeyCountPair; 431 | typedef std::map< ID3DX11Effect*, EffectKeyCountPair > ReferenceCountMap; 432 | ReferenceCountMap referenceCountMap; 433 | 434 | typedef std::map< ID3DX11Effect*, ID3DX11Effect* > Clone2ReferenceMap; 435 | Clone2ReferenceMap clone2ReferenceMap; 436 | 437 | // We need to keep track of dx11ShaderNodes at all times, 438 | // even when compilation failed and we have no ID3DX11Effect 439 | // to deal with. This will allow the "Reload" button to work 440 | // after a shader file failed to compile. 441 | typedef std::set< dx11ShaderNode* > NodeSet; 442 | typedef std::map< MString, NodeSet, MStringSorter > Path2NodesMap; 443 | Path2NodesMap path2NodesMap; 444 | }; 445 | 446 | //! Acquire effect from specified fileName 447 | //! If a reference effect is found for this fileName, return a cloned instance 448 | //! Update collection keeps track of : 449 | //! cloned effect -> reference effect 450 | //! fileName -> node 451 | ID3DX11Effect* EffectCollection::acquire(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName) 452 | { 453 | ID3DX11Effect* effect = NULL; 454 | 455 | EffectKey key = { device, fileName, fileTimeStamp(fileName) } ; 456 | 457 | // Find reference in cache 458 | Key2ReferenceEffectMap::const_iterator it = key2ReferenceEffectMap.find(key); 459 | if(it != key2ReferenceEffectMap.end()) 460 | { 461 | ID3DX11Effect* reference = it->second; 462 | effect = acquire(node, device, fileName, reference); 463 | } 464 | 465 | return effect; 466 | } 467 | 468 | //! Acquire effect from reference 469 | //! Return a cloned instance of the effect 470 | //! Update collection keeps track of : 471 | //! cloned effect -> reference effect 472 | //! fileName -> node 473 | ID3DX11Effect* EffectCollection::acquire(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, ID3DX11Effect* reference, ID3DX11Effect* source ) 474 | { 475 | // Keep track of fileName -> node lookup, whenever the effect was loaded or not 476 | path2NodesMap[fileName].insert(node); 477 | 478 | if( reference == NULL ) 479 | return NULL; 480 | if( source == NULL) 481 | source = reference; 482 | 483 | // Add the reference in cache if not in yet. 484 | EffectKey key = { device, fileName, fileTimeStamp(fileName) } ; 485 | { 486 | Key2ReferenceEffectMap::const_iterator it = key2ReferenceEffectMap.find(key); 487 | if(it == key2ReferenceEffectMap.end()) { 488 | key2ReferenceEffectMap.insert( std::make_pair(key, reference) ); 489 | } 490 | } 491 | 492 | // Clone effect 493 | ID3DX11Effect* effect = NULL; 494 | HRESULT hr = source->CloneEffect(0, &effect); 495 | if( FAILED( hr ) || effect == NULL ) 496 | return NULL; 497 | 498 | // Increase the number of clone for this reference 499 | // Equivalent to the number of time this effect is used 500 | { 501 | ReferenceCountMap::iterator it = referenceCountMap.find(reference); 502 | if(it == referenceCountMap.end()) 503 | { 504 | // Not there yet, set count to 1 and register key 505 | referenceCountMap.insert( std::make_pair(reference, std::make_pair(key, 1) ) ); 506 | } 507 | else 508 | { 509 | // Already there add 1 510 | ++(it->second.second); 511 | } 512 | } 513 | 514 | // Keep track of clone -> reference lookup 515 | clone2ReferenceMap.insert( std::make_pair(effect, reference) ); 516 | 517 | return effect; 518 | } 519 | 520 | //! Release the effect from cache, 521 | //! and release the reference if this effect was it last clone 522 | void EffectCollection::release(dx11ShaderNode* node, ID3DX11Effect *effect, const MString& fileName) 523 | { 524 | if (effect) 525 | { 526 | Clone2ReferenceMap::iterator it = clone2ReferenceMap.find(effect); 527 | if(it != clone2ReferenceMap.end()) 528 | { 529 | ID3DX11Effect* reference = it->second; 530 | 531 | ReferenceCountMap::iterator it2 = referenceCountMap.find(reference); 532 | if(it2 != referenceCountMap.end()) 533 | { 534 | // This was the last clone for this reference, we can release it 535 | if(it2->second.second == 1) 536 | { 537 | EffectKey &key = it2->second.first; 538 | key2ReferenceEffectMap.erase(key); 539 | referenceCountMap.erase(it2); 540 | reference->Release(); 541 | } 542 | else 543 | { 544 | --(it2->second.second); 545 | } 546 | } 547 | 548 | clone2ReferenceMap.erase(it); 549 | } 550 | 551 | effect->Release(); 552 | } 553 | 554 | // Remove this node from the fileName -> nodes lookup 555 | path2NodesMap[fileName].erase(node); 556 | // No more not for this fileName, clear it 557 | if (path2NodesMap[fileName].empty()) 558 | path2NodesMap.erase(fileName); 559 | } 560 | 561 | //! Return the effect used as reference and the effect file name 562 | ID3DX11Effect* EffectCollection::getReferenceEffectAndFileName(ID3DX11Effect *effect, MString& fileName) const 563 | { 564 | ID3DX11Effect* reference = NULL; 565 | 566 | Clone2ReferenceMap::const_iterator it = clone2ReferenceMap.find(effect); 567 | if(it != clone2ReferenceMap.end()) 568 | { 569 | reference = it->second; 570 | 571 | Key2ReferenceEffectMap::const_iterator it2 = key2ReferenceEffectMap.begin(); 572 | Key2ReferenceEffectMap::const_iterator it2End = key2ReferenceEffectMap.end(); 573 | for(; it2 != it2End; ++it2) 574 | { 575 | if(it2->second == reference) 576 | { 577 | fileName = it2->first.fileName; 578 | break; 579 | } 580 | } 581 | } 582 | 583 | return reference; 584 | } 585 | 586 | void EffectCollection::getNodesUsingEffect(const MString& fileName, ShaderNodeList &nodes) const 587 | { 588 | Path2NodesMap::const_iterator itNodeSet = path2NodesMap.find(fileName); 589 | if (itNodeSet != path2NodesMap.end()) 590 | { 591 | const NodeSet& nodeSet = itNodeSet->second; 592 | for (NodeSet::const_iterator itNode = nodeSet.begin(); itNode != nodeSet.end(); ++itNode) 593 | { 594 | nodes.push_back(*itNode); 595 | } 596 | } 597 | } 598 | 599 | static EffectCollection gEffectCollection; 600 | 601 | class CompiledEffectCache { 602 | // Very basic LRU cache for effect files: 603 | public: 604 | CompiledEffectCache(); 605 | ~CompiledEffectCache(); 606 | static CompiledEffectCache* get(); 607 | ID3DX11Effect* find( ID3D11Device* device, const MString& fileName ); 608 | void add(ID3D11Device* device, const MString& fileName, ID3DX11Effect* effect ); 609 | private: 610 | struct CacheData { 611 | CacheData(ID3D11Device* device, const MString& fileName, ID3DX11Effect* effect, int firstAccess); 612 | ~CacheData(); 613 | ID3D11Device* mDevice; 614 | MString mFileName; 615 | time_t mTimeStamp; 616 | ID3DX11Effect* mEffect; 617 | int mLastAccess; 618 | private: 619 | CacheData(const CacheData&); 620 | const CacheData& operator=(const CacheData&); 621 | }; 622 | std::list mCached; 623 | int mAccessClock; 624 | static const size_t kCacheSize = 8; 625 | MCallbackId mExitCallback; 626 | MCallbackId mFileNewCallback; 627 | static void flushCache( void *data); 628 | static CompiledEffectCache* sCachePtr; 629 | }; 630 | 631 | CompiledEffectCache::CacheData::CacheData(ID3D11Device* device, const MString& fileName, ID3DX11Effect* effect, int firstAccess) 632 | : mDevice(device) 633 | , mFileName(fileName) 634 | , mEffect(NULL) 635 | , mLastAccess(firstAccess) 636 | { 637 | if (effect) 638 | effect->CloneEffect(0, &mEffect); 639 | mTimeStamp = fileTimeStamp(fileName); 640 | } 641 | 642 | CompiledEffectCache::CacheData::~CacheData() 643 | { 644 | if (mEffect) 645 | mEffect->Release(); 646 | } 647 | 648 | CompiledEffectCache::CompiledEffectCache() : mAccessClock(0) { 649 | mExitCallback = MSceneMessage::addCallback(MSceneMessage::kMayaExiting, CompiledEffectCache::flushCache ); 650 | mFileNewCallback = MSceneMessage::addCallback(MSceneMessage::kBeforeNew, CompiledEffectCache::flushCache ); 651 | } 652 | 653 | CompiledEffectCache::~CompiledEffectCache() 654 | { 655 | std::list::iterator itCache = mCached.begin(); 656 | for ( ; itCache != mCached.end(); ++itCache ) 657 | { 658 | delete *itCache; 659 | } 660 | MSceneMessage::removeCallback( mExitCallback ); 661 | MSceneMessage::removeCallback( mFileNewCallback ); 662 | } 663 | 664 | void CompiledEffectCache::flushCache( void *data) 665 | { 666 | delete sCachePtr; 667 | sCachePtr = NULL; 668 | } 669 | 670 | CompiledEffectCache* CompiledEffectCache::get() 671 | { 672 | if (!sCachePtr) 673 | sCachePtr = new CompiledEffectCache(); 674 | return sCachePtr; 675 | } 676 | 677 | CompiledEffectCache* CompiledEffectCache::sCachePtr = NULL; 678 | 679 | ID3DX11Effect* CompiledEffectCache::find( ID3D11Device* device, const MString& fileName ) 680 | { 681 | ID3DX11Effect* effect = NULL; 682 | // For small caches, a linear search is fine. 683 | std::list::iterator itCache = mCached.begin(); 684 | for ( ; itCache != mCached.end(); ++itCache ) 685 | { 686 | CompiledEffectCache::CacheData *cacheItem(*itCache); 687 | if ( cacheItem->mDevice == device && 688 | cacheItem->mFileName == fileName && 689 | cacheItem->mTimeStamp == fileTimeStamp(fileName) ) 690 | { 691 | cacheItem->mLastAccess = ++mAccessClock; 692 | cacheItem->mEffect->CloneEffect(0, &effect); 693 | break; 694 | } 695 | } 696 | 697 | return effect; 698 | } 699 | 700 | void CompiledEffectCache::add(ID3D11Device* device, const MString& fileName, ID3DX11Effect* effect ) 701 | { 702 | if (mCached.size() > kCacheSize) 703 | { 704 | std::list::iterator itCache = mCached.begin(); 705 | std::list::iterator oldestItem = itCache; 706 | itCache++; 707 | for ( ; itCache != mCached.end(); ++itCache ) 708 | { 709 | if ( (*itCache)->mLastAccess < (*oldestItem)->mLastAccess ) 710 | oldestItem = itCache; 711 | } 712 | CacheData* oldData(*oldestItem); 713 | mCached.erase(oldestItem); 714 | delete oldData; 715 | } 716 | CacheData* newData(new CacheData(device, fileName, effect, ++mAccessClock)); 717 | if (newData->mEffect) 718 | mCached.push_back( newData ); 719 | else 720 | delete newData; 721 | } 722 | } 723 | 724 | /* 725 | Remove effect from collection and also remove reference if it was the last effect corresponding to file path. 726 | */ 727 | void CDX11EffectCompileHelper::releaseEffect(dx11ShaderNode* node, ID3DX11Effect* effect, const MString& fileName) 728 | { 729 | MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(fileName); 730 | 731 | gEffectCollection.release(node, effect, resolvedFileName); 732 | } 733 | 734 | /* 735 | Get the absolute file path 736 | */ 737 | MString CDX11EffectCompileHelper::resolveShaderFileName(const MString& fileName, bool* fileExists) 738 | { 739 | MString resolvedFileName = fileName; 740 | 741 | // If the fileName is absolute, no resolve needed, we keep the original full path 742 | if( MFileObject::isAbsolutePath(fileName) == false ) 743 | { 744 | CIncludeHelper includeHelper; 745 | resolvedFileName = includeHelper.resolveFileName(fileName.asChar()); 746 | } 747 | 748 | if( fileExists != NULL ) 749 | { 750 | MFileObject file; 751 | file.setRawFullName( resolvedFileName ); 752 | *fileExists = file.exists(); 753 | } 754 | 755 | return resolvedFileName; 756 | } 757 | 758 | /* 759 | Load and compile a text shader file. 760 | - The shader is first searched in the collection, if a match is found a clone is returned 761 | and automatically added to the collection. 762 | - Else it's searched in the LRU, if found it will be cloned and added to the collection. 763 | - Finally if no match is found, the shader file is loaded and compiled, 764 | and the effect is added to the collection as reference. 765 | */ 766 | ID3DX11Effect* CDX11EffectCompileHelper::build(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, MString &errorLog, bool useStrictness) 767 | { 768 | bool fileExits = false; 769 | MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(fileName, &fileExits); 770 | if(fileExits == false) 771 | { 772 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorFileNotFound, resolvedFileName ); 773 | errorLog += msg; 774 | return NULL; 775 | } 776 | 777 | bool compiledEffect = false; 778 | if( isValidEffectFile(resolvedFileName, compiledEffect) == false ) 779 | { 780 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorInvalidEffectFile, resolvedFileName ); 781 | errorLog += msg; 782 | return NULL; 783 | } 784 | 785 | // Acquire effect from collection if it was already loaded once and will return a clone 786 | ID3DX11Effect *effect = gEffectCollection.acquire(node, device, resolvedFileName); 787 | if( effect == NULL ) { 788 | 789 | effect = CompiledEffectCache::get()->find(device, resolvedFileName); 790 | if( effect == NULL ) { 791 | 792 | if( resolvedFileName != fileName && MFileObject::isAbsolutePath(fileName) ) 793 | { 794 | MStringArray args; 795 | args.append(fileName); 796 | args.append(resolvedFileName); 797 | 798 | MString msg = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorAbsolutePathNotFound, args ); 799 | errorLog += msg; 800 | } 801 | 802 | CIncludeHelper includeHelper; 803 | includeHelper.setReferencePath(resolvedFileName); 804 | 805 | ID3DBlob *shader = NULL; 806 | ID3DBlob *error = NULL; 807 | HRESULT hr = S_FALSE; 808 | 809 | if( compiledEffect ) 810 | { 811 | FILE* file = fopen(resolvedFileName.asChar(), "rb"); 812 | if(file) 813 | { 814 | // Get the file size 815 | fseek(file, 0, SEEK_END); 816 | long size = ftell(file); 817 | fseek(file, 0, SEEK_SET); 818 | 819 | // Get the file content 820 | hr = D3DCreateBlob(size, &shader); 821 | if( SUCCEEDED( hr ) ) 822 | { 823 | fread(shader->GetBufferPointer(), 1, size, file); 824 | } 825 | fclose(file); 826 | } 827 | } 828 | else 829 | { 830 | unsigned int compileFlags = getShaderCompileFlags(useStrictness); 831 | D3D10_SHADER_MACRO* macros = getD3DMacros(); 832 | #if _MSC_VER < 1700 833 | hr = D3DX11CompileFromFile(resolvedFileName.asChar(), macros, &includeHelper, NULL, /*MSG0*/"fx_5_0", compileFlags, 0, NULL, &shader, &error, NULL); 834 | #else 835 | hr = D3DCompileFromFile(resolvedFileName.asWChar(), macros, &includeHelper, NULL, /*MSG0*/"fx_5_0", compileFlags, 0, &shader, &error); 836 | #endif 837 | } 838 | 839 | if( FAILED( hr ) || shader == NULL ) 840 | { 841 | pushError(fileName, errorLog, error); 842 | } 843 | else if( shader ) 844 | { 845 | hr = D3DX11CreateEffectFromMemory(shader->GetBufferPointer(), shader->GetBufferSize(), 0, device, &effect); 846 | if( FAILED( hr ) || effect == NULL ) 847 | { 848 | pushError(fileName, errorLog, error); 849 | } 850 | } 851 | 852 | if( shader ) { 853 | shader->Release(); 854 | } 855 | 856 | if( compiledEffect == false && useStrictness == false && effect != NULL && effectHasHullShader(effect) ) { 857 | // if the effect has a hull shader we need to recompile it 858 | // with strict flag otherwise it won't support the tesselation properly : 859 | // for example, the geometry may not be visible 860 | effect->Release(); 861 | effect = CDX11EffectCompileHelper::build(node, device, fileName, errorLog, true /*useStrictness*/); 862 | 863 | // return now, skip the add to cache, already done in build() 864 | return effect; 865 | } 866 | 867 | // Effect was compiled, 868 | // Add it to LRU cache 869 | CompiledEffectCache::get()->add(device, resolvedFileName, effect); 870 | } // CompiledEffectCache::get() 871 | 872 | // The effect was either found in the CompiledEffectCache or compiled, 873 | // Acquire effect from collection, will register the compiled effect as reference and will return a clone 874 | effect = gEffectCollection.acquire(node, device, resolvedFileName, effect); 875 | } // gEffectCollection.acquire() 876 | 877 | return effect; 878 | } 879 | 880 | /* 881 | During a duplicate, we already have an effect to use as reference. 882 | The source effect will be cloned, and the result added to the cache. 883 | */ 884 | ID3DX11Effect* CDX11EffectCompileHelper::build(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, ID3DX11Effect* effectSource, MString &errorLog) 885 | { 886 | MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(fileName); 887 | 888 | ID3DX11Effect *effect = NULL; 889 | 890 | // Find effectSource in collection 891 | // Will gives us the original reference effect for this effect and the resolved fileName. 892 | MString referenceResolvedFileName; 893 | ID3DX11Effect *reference = gEffectCollection.getReferenceEffectAndFileName(effectSource, referenceResolvedFileName); 894 | if(reference != NULL && resolvedFileName == referenceResolvedFileName) 895 | { 896 | // Acquire effect from collection 897 | effect = gEffectCollection.acquire(node, device, resolvedFileName, reference, effectSource); 898 | } 899 | 900 | return effect; 901 | } 902 | 903 | /* 904 | Load a precompiled effect. 905 | The effect is not stored in any cache, as the loading of a compiled effect is already fast enough. 906 | */ 907 | ID3DX11Effect* CDX11EffectCompileHelper::build(dx11ShaderNode* node, ID3D11Device* device, const void* buffer, unsigned int dataSize, MString &errorLog, bool useStrictness) 908 | { 909 | unsigned int compileFlags = getShaderCompileFlags(useStrictness); 910 | D3D10_SHADER_MACRO* macros = getD3DMacros(); 911 | CIncludeHelper includeHelper; 912 | 913 | ID3DX11Effect *effect = NULL; 914 | ID3DBlob *shader = NULL; 915 | ID3DBlob *error = NULL; 916 | HRESULT hr = S_FALSE; 917 | #if _MSC_VER < 1700 918 | hr = D3DX11CompileFromMemory((char*)buffer, dataSize, NULL, macros, &includeHelper, "", "fx_5_0", compileFlags, 0, NULL, &shader, &error, NULL); 919 | #else 920 | hr = D3DCompile((char*)buffer, dataSize, NULL, macros, &includeHelper, "", "fx_5_0", compileFlags, 0, &shader, &error); 921 | #endif 922 | if( FAILED( hr ) || shader == NULL ) 923 | { 924 | pushError(errorLog, error); 925 | } 926 | else if( shader ) 927 | { 928 | hr = D3DX11CreateEffectFromMemory(shader->GetBufferPointer(), shader->GetBufferSize(), 0, device, &effect); 929 | if( FAILED( hr ) || effect == NULL ) 930 | { 931 | pushError(errorLog, error); 932 | } 933 | } 934 | 935 | if( shader ) { 936 | shader->Release(); 937 | } 938 | 939 | if( useStrictness == false && effect != NULL && effectHasHullShader(effect) ) { 940 | // if the effect has a hull shader we need to recompile it 941 | // with strict flag otherwise it won't support the tesselation properly : 942 | // for example, the geometry may not be visible 943 | effect->Release(); 944 | effect = CDX11EffectCompileHelper::build(node, device, buffer, dataSize, errorLog, true /*useStrictness*/); 945 | } 946 | 947 | return effect; 948 | } 949 | 950 | /* 951 | Get all the nodes that use the specified file shader. 952 | The collection keeps track of which shader is used by which nodes. 953 | */ 954 | void CDX11EffectCompileHelper::getNodesUsingEffect(const MString& fileName, ShaderNodeList &nodes) 955 | { 956 | MString resolvedFileName = CDX11EffectCompileHelper::resolveShaderFileName(fileName); 957 | 958 | gEffectCollection.getNodesUsingEffect(resolvedFileName, nodes); 959 | } 960 | -------------------------------------------------------------------------------- /dx11ShaderCompileHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ShaderCompileHelper_h_ 2 | #define _dx11ShaderCompileHelper_h_ 3 | //- 4 | // ========================================================================== 5 | // Copyright 1995,2006,2008,2011 Autodesk, Inc. All rights reserved. 6 | // 7 | // Use of this software is subject to the terms of the Autodesk 8 | // license agreement provided at the time of installation or download, 9 | // or which otherwise accompanies this software in either electronic 10 | // or hard copy form. 11 | // ========================================================================== 12 | //+ 13 | 14 | #include 15 | 16 | struct ID3D11Device; 17 | struct ID3DX11Effect; 18 | class MString; 19 | class dx11ShaderNode; 20 | 21 | 22 | /*! 23 | HLSL shader files come in two flavors: as plain text (.fx) or in binary format (.fxo) 24 | Since a binary file is a precompiled shader it loads really fast. 25 | For text files, the shader needs to be compiled at runtime, depending on the optimization 26 | level and the complexity of the shader this can take quite a while. 27 | For that reason a caching system was introduced for .fx shader files. 28 | 29 | The cache system is not directly accessible to the dx11shader, instead it can use the 30 | following interfaces to load/release effects. 31 | */ 32 | 33 | namespace CDX11EffectCompileHelper 34 | { 35 | // Release the effect from the specified node 36 | void releaseEffect(dx11ShaderNode* node, ID3DX11Effect* effect, const MString& fileName); 37 | 38 | // Build an effect from an external file 39 | ID3DX11Effect* build(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, MString &errorLog, bool useStrictness = false); 40 | 41 | // Clone an effect - used for the duplicate operation 42 | ID3DX11Effect* build(dx11ShaderNode* node, ID3D11Device* device, const MString& fileName, ID3DX11Effect* effectSource, MString &errorLog); 43 | 44 | // Load a compiled effect 45 | ID3DX11Effect* build(dx11ShaderNode* node, ID3D11Device* device, const void* buffer, unsigned int dataSize, MString &errorLog, bool useStrictness = false); 46 | 47 | // Get the absolute path of an effect file 48 | MString resolveShaderFileName(const MString& shaderPath, bool* fileExists = NULL); 49 | 50 | // Get the list of the nodes that use the specified shader file 51 | typedef std::list< dx11ShaderNode* > ShaderNodeList; 52 | void getNodesUsingEffect(const MString& fileName, ShaderNodeList &nodes); 53 | }; 54 | 55 | #endif //_dx11ShaderCompilHelper_h_ 56 | -------------------------------------------------------------------------------- /dx11ShaderCreateUI.mel: -------------------------------------------------------------------------------- 1 | // 2 | // Description: 3 | // Create UI components for dx11Shader plugin 4 | // 5 | 6 | // Close the preference window if it is open before adding the new panel for dx11Shader: 7 | proc closePreferencesWindow() 8 | { 9 | global string $gPreferenceWindow; 10 | if (`window -exists $gPreferenceWindow`) { 11 | string $result; 12 | string $confirmMessage = getPluginResource( "dx11Shader", "kPrefSavePrefsOrNotMsg" ); 13 | string $save = `uiRes "s_TdialogStrings.rSave"`; 14 | string $dontSave = `uiRes "s_TdialogStrings.rDontSave"`; 15 | 16 | $result = `confirmDialog -title (getPluginResource( "dx11Shader", "kPrefSaveMsg" )) 17 | -message $confirmMessage 18 | -button $save 19 | -button $dontSave 20 | -defaultButton $save 21 | -cancelButton $dontSave`; 22 | 23 | if ($result == $save) { 24 | savePrefsChanges; 25 | } 26 | else { 27 | cancelPrefsChanges; 28 | } 29 | } 30 | } 31 | 32 | global proc prefsFrameLayoutCreateDx11Shader() 33 | { 34 | frameLayout -labelVisible false -borderVisible false -marginWidth 10 -marginHeight 10; 35 | columnLayout -adj true prefDx11ShaderCol; 36 | } 37 | 38 | global proc prefsSetOptVarToDefaultDx11Shader() 39 | { 40 | optionVar -sv "dx11ShaderDefaultEffect" "AutodeskUberShader.fxo"; 41 | } 42 | 43 | global proc dx11ShaderRefreshValueCtrls() 44 | { 45 | global string $gPreferenceWindow; 46 | if (!`window -exists $gPreferenceWindow`) { 47 | return; 48 | } 49 | 50 | setParent $gPreferenceWindow; 51 | string $parent = "prefDx11ShaderCol"; 52 | 53 | if (`columnLayout -q -numberOfChildren $parent` == 0) { 54 | return; 55 | } 56 | 57 | textField -e -fileName `optionVar -q dx11ShaderDefaultEffect` dx11ShaderDefaultEffectField; 58 | } 59 | 60 | global proc prefsHoldCurrentStateDx11Shader(string $mode) 61 | { 62 | // Avoid missing value updates by assuming fields are all changed. 63 | prefDx11ShaderDefaultEffectValueUpdate; 64 | 65 | if ($mode == "save") { 66 | optionVar -sv "dx11ShaderDefaultEffectHold" `optionVar -q dx11ShaderDefaultEffect`; 67 | } else if ($mode == "restore") { 68 | optionVar -sv "dx11ShaderDefaultEffect" `optionVar -q dx11ShaderDefaultEffectHold`; 69 | } else { // "remove" 70 | // Remove the temporary option vars so they don't get saved out 71 | optionVar -remove "dx11ShaderDefaultEffectHold"; 72 | } 73 | 74 | dx11ShaderRefreshValueCtrls; 75 | } 76 | 77 | global proc prefDx11ShaderDefaultEffectBrowser() 78 | { 79 | // Start in current file's directory if possible. 80 | string $sStartingdir = `textField -q -fileName dx11ShaderDefaultEffectField`; 81 | $sStartingdir = `match ".*/" $sStartingdir`; 82 | 83 | string $fileDialogCmd = "fileDialog2"; 84 | $fileDialogCmd += (" -cap \"" + (getPluginResource( "dx11Shader", "kPrefFileOpen")) + "\""); 85 | $fileDialogCmd += (" -fm 1"); 86 | if( $sStartingdir != "") 87 | $fileDialogCmd += (" -dir \"" + $sStartingdir + "\""); 88 | 89 | // Invoke the file browser dialog. 90 | string $file[] = `eval $fileDialogCmd`; 91 | if (size($file) > 0 && $file[0] != "") 92 | { 93 | string $path = $file[0]; 94 | 95 | // ... strip the QT's .* postfix 96 | // OS native dialog does not have the .* postfix if the filter is * or *.* 97 | if ( endsWith($path, ".*") ) 98 | { 99 | $path = substring($path, 1, size($path)-2); 100 | } 101 | 102 | textField -e -fileName $path dx11ShaderDefaultEffectField; 103 | prefDx11ShaderDefaultEffectValueUpdate(); 104 | } 105 | } 106 | 107 | global proc prefDx11ShaderDefaultEffectValueUpdate() 108 | { 109 | if (`textField -exists dx11ShaderDefaultEffectField`) { 110 | string $newVal = `textField -q -fileName dx11ShaderDefaultEffectField`; 111 | optionVar -sv "dx11ShaderDefaultEffect" $newVal; 112 | } 113 | } 114 | 115 | global proc prefsCreateDx11Shader() 116 | { 117 | global string $gPreferenceWindow; 118 | setParent $gPreferenceWindow; 119 | string $parent = "prefDx11ShaderCol"; 120 | 121 | // Check to see if this has been created already. 122 | // 123 | if (`columnLayout -q -numberOfChildren $parent` > 0) { 124 | return; 125 | } 126 | 127 | // Create the UI 128 | // 129 | setParent $parent; 130 | setUITemplate -pushTemplate prefsTemplate; 131 | 132 | // This is used to force the width to fill the window 133 | separator -style "none" -h 1; 134 | string $editFrameLayoutName = getPluginResource( "dx11Shader", "kPrefDefaultEffectFile"); 135 | 136 | frameLayout -label $editFrameLayoutName; 137 | columnLayout -adjustableColumn true ; 138 | 139 | rowLayout -nc 2 140 | -cw2 300 25 141 | -cal 1 "both" 142 | -cal 2 "left" 143 | -ct2 "both" "left" 144 | -adj 1; 145 | 146 | textField -fileName (`optionVar -q "dx11ShaderDefaultEffect"`) 147 | -cc "prefDx11ShaderDefaultEffectValueUpdate();" 148 | dx11ShaderDefaultEffectField; 149 | symbolButton -image "navButtonBrowse.png" -c "prefDx11ShaderDefaultEffectBrowser()" browseBtn; 150 | 151 | setParent $parent; 152 | 153 | setUITemplate -popTemplate; 154 | 155 | dx11ShaderRefreshValueCtrls; 156 | } 157 | 158 | global proc dx11ShaderCreateUI() 159 | { 160 | // We have renamed MayaUberShader.fx to AutodeskUberShader.fx, so we 161 | // make sure preference settings of previous Maya versions do not continue to point to the old shader: 162 | if (!`optionVar -exists dx11ShaderDefaultEffect` || `optionVar -q dx11ShaderDefaultEffect` == "MayaUberShader.fxo") 163 | prefsSetOptVarToDefaultDx11Shader; 164 | 165 | closePreferencesWindow(); 166 | addCustomPrefsTab("prefsCreateDx11Shader", 167 | "prefsFrameLayoutCreateDx11Shader", 168 | "dx11ShaderRefreshValueCtrls", 169 | "prefsHoldCurrentStateDx11Shader", 170 | "prefsSetOptVarToDefaultDx11Shader", 171 | (getPluginResource( "dx11Shader", "kPrefDx11ShaderPanel")), 172 | (getPluginResource( "dx11Shader", "kPrefDx11ShaderTab"))); 173 | } 174 | 175 | global proc dx11ShaderDeleteUI() 176 | { 177 | closePreferencesWindow(); 178 | deleteCustomPrefsTab("prefsCreateDx11Shader"); 179 | } 180 | -------------------------------------------------------------------------------- /dx11ShaderInitStrings.mel: -------------------------------------------------------------------------------- 1 | // PLUGIN NAME: dx11Shader 2 | 3 | // FILE: dx11ShaderInitStrings.mel 4 | 5 | // DESCRIPTION: Register script resources for the "dx11Shader" plugin 6 | 7 | 8 | global proc dx11ShaderInitStrings() 9 | { 10 | loadPluginLanguageResources("dx11Shader", "dx11Shader.pres.mel"); 11 | 12 | // The code that tries to generate nice UI names from CamelCase object names has problems with the number 11, 13 | // Let's help by providing a nice UI name, 14 | string $niceName = getPluginResource( "dx11Shader", "kNiceNodeName" ); 15 | displayString -replace -value $niceName "n_dx11Shader.niceName"; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /dx11ShaderOverride.cpp: -------------------------------------------------------------------------------- 1 | //- 2 | // Copyright 2011 Autodesk, Inc. All rights reserved. 3 | // 4 | // Use of this software is subject to the terms of the Autodesk license 5 | // agreement provided at the time of installation or download, or which 6 | // otherwise accompanies this software in either electronic or hard copy form. 7 | //+ 8 | 9 | #if _MSC_VER >= 1700 10 | #pragma warning( disable: 4005 ) 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | static const bool DO_CUSTOM_DRAW = true; 18 | static const bool PRINT_DEBUG_INFO = false; 19 | 20 | MHWRender::MPxShaderOverride* dx11ShaderOverride::Creator(const MObject& obj) 21 | { 22 | return new dx11ShaderOverride(obj); 23 | } 24 | 25 | dx11ShaderOverride::dx11ShaderOverride(const MObject& obj) 26 | : MHWRender::MPxShaderOverride(obj) 27 | , fShaderNode(NULL) 28 | , fGeometryVersionId(0) 29 | , fBBoxExtraScale(1.0f) 30 | , fStates() 31 | { 32 | // Get an early peek to the shader node, so we can have the scale value, 33 | // before the shader can be discarded by the clipping. 34 | dx11ShaderNode* shaderNode = (dx11ShaderNode*)MPxHardwareShader::getHardwareShaderPtr(const_cast(obj)); 35 | if(shaderNode) 36 | { 37 | fBBoxExtraScale = shaderNode->boundingBoxExtraScale(); 38 | } 39 | } 40 | 41 | dx11ShaderOverride::~dx11ShaderOverride() 42 | { 43 | } 44 | 45 | MString dx11ShaderOverride::initialize(const MInitContext& initContext,MInitFeedback& initFeedback) 46 | { 47 | // Get the hardware shader node from the MObject 48 | // ----------------------------------------------- 49 | fShaderNode = NULL; 50 | if (initContext.shader != MObject::kNullObj) { 51 | MInitContext* nonConst = const_cast(&initContext); 52 | fShaderNode =(dx11ShaderNode*)MPxHardwareShader::getHardwareShaderPtr(nonConst->shader); 53 | } 54 | 55 | // Add geometry requirements based on 56 | // ----------------------------------------------- 57 | if (fShaderNode) 58 | { 59 | int count = fShaderNode->techniqueCount(); 60 | int activeTechnique = fShaderNode->activeTechnique(); 61 | if (activeTechnique >= 0 && activeTechnique < count) 62 | { 63 | // add requirements 64 | addGeometryRequirements(*fShaderNode->vertexBufferDescLists()); 65 | 66 | // Trying to send the signature anyhow in order not to have the assert 67 | // (maybe not necessary because for custom draw we create the input 68 | // layout manually) 69 | dx11ShaderDX11EffectTechnique* technique = fShaderNode->technique(); 70 | if (technique) 71 | { 72 | int passCount = fShaderNode->passCount(); 73 | if (passCount > 0) 74 | { 75 | // Take signature from first pass (assume all equal) 76 | dx11ShaderDX11Pass* dxPass = technique->GetPassByIndex(0); 77 | if (dxPass) 78 | { 79 | D3DX11_PASS_DESC descPass; 80 | dxPass->GetDesc(&descPass); 81 | addShaderSignature( descPass.pIAInputSignature, descPass.IAInputSignatureSize); 82 | } 83 | } 84 | } 85 | } 86 | 87 | // custom primitive types can be used by shader overrides. 88 | // This code is a simple example to show the mechanics of how that works. 89 | // Here we declare a custom custom indexing requirements. 90 | // The customPrimitiveGeneratorName will be used to look up a registered 91 | // MPxPrimitiveGenerator that will handle the generation of the index buffer. 92 | // The example primitive generator is registered at startup by this plugin. 93 | MString customPrimitiveGeneratorName = fShaderNode->techniqueIndexBufferType(); 94 | // Always set the custom indexing requirement, even it the name is empty; 95 | // That will clear any custom name that was previously set (may happen during reload). 96 | //if (customPrimitiveGeneratorName.length() > 0) 97 | { 98 | MHWRender::MIndexBufferDescriptor indexingRequirement 99 | (MHWRender::MIndexBufferDescriptor::kCustom, customPrimitiveGeneratorName, MHWRender::MGeometry::kTriangles); 100 | addIndexingRequirement(indexingRequirement); 101 | } 102 | 103 | // Sync version ids 104 | fGeometryVersionId = fShaderNode->geometryVersionId(); 105 | } 106 | 107 | // Build key string, note that if any attribute on the node changes that 108 | // would affect the value of this string, then we must trigger rebuild of 109 | // the shader 110 | MString result = MString("Autodesk Maya dx11ShaderOverride, nodeName="); 111 | result += fShaderNode ? fShaderNode->name() : MString("null"); 112 | result += MString(", effectFileName="); 113 | result += fShaderNode ? fShaderNode->effectName() : MString("null"); 114 | result += MString(", technique="); 115 | result += (fShaderNode) ? fShaderNode->activeTechniqueName() : MString("null"); 116 | return result; 117 | } 118 | 119 | void dx11ShaderOverride::updateDG(MObject object) 120 | { 121 | } 122 | 123 | void dx11ShaderOverride::updateDevice() 124 | { 125 | } 126 | 127 | void dx11ShaderOverride::endUpdate() 128 | { 129 | } 130 | 131 | bool dx11ShaderOverride::handlesDraw(MHWRender::MDrawContext& context) 132 | { 133 | const MHWRender::MPassContext & passCtx = context.getPassContext(); 134 | const MStringArray & passSem = passCtx.passSemantics(); 135 | 136 | // For color passes, only handle if there isn't already 137 | // a global override. This is the same as the default 138 | // logic for this method in MPxShaderOverride 139 | // 140 | bool handlePass = false; 141 | for (unsigned int i=0; itechniqueHandlesContext(passSem[i]); 160 | } 161 | } 162 | return handlePass; 163 | } 164 | 165 | void dx11ShaderOverride::activateKey(MHWRender::MDrawContext& context, const MString& /*key*/) 166 | { 167 | if (fShaderNode) { 168 | MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); 169 | if (theRenderer) 170 | { 171 | dx11ShaderDX11Device* dxDevice = (dx11ShaderDX11Device*)theRenderer->GPUDeviceHandle(); 172 | if (dxDevice) 173 | { 174 | ID3D11DeviceContext* dxContext = NULL; 175 | dxDevice->GetImmediateContext(&dxContext); 176 | if (dxContext) 177 | { 178 | fShaderNode->backupStates(dxContext, fStates); 179 | 180 | dxContext->VSSetShader(NULL, NULL, 0); 181 | dxContext->PSSetShader(NULL, NULL, 0); 182 | dxContext->GSSetShader(NULL, NULL, 0); 183 | dxContext->HSSetShader(NULL, NULL, 0); 184 | dxContext->DSSetShader(NULL, NULL, 0); 185 | 186 | dxContext->Release(); 187 | } 188 | } 189 | } 190 | 191 | fShaderNode->updateShaderBasedGeoChanges(); 192 | } 193 | } 194 | 195 | bool dx11ShaderOverride::draw( 196 | MHWRender::MDrawContext& context, 197 | const MHWRender::MRenderItemList& renderItemList) const 198 | { 199 | // Get effect wrapper 200 | if (!fShaderNode) return false; 201 | 202 | // Sample code to debug pass information 203 | static const bool debugPassInformation = false; 204 | if (debugPassInformation) 205 | { 206 | const MHWRender::MPassContext & passCtx = context.getPassContext(); 207 | const MString & passId = passCtx.passIdentifier(); 208 | const MStringArray & passSem = passCtx.passSemantics(); 209 | printf("dx11 shader drawing in pass[%s], semantic[", passId.asChar()); 210 | for (unsigned int i=0; irender(context, renderItemList); 216 | } 217 | 218 | void dx11ShaderOverride::terminateKey(MHWRender::MDrawContext& context, const MString& /*key*/) 219 | { 220 | if (fShaderNode) { 221 | MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); 222 | if (theRenderer) 223 | { 224 | dx11ShaderDX11Device* dxDevice = (dx11ShaderDX11Device*)theRenderer->GPUDeviceHandle(); 225 | if (dxDevice) 226 | { 227 | ID3D11DeviceContext* dxContext = NULL; 228 | dxDevice->GetImmediateContext(&dxContext); 229 | if (dxContext) 230 | { 231 | fShaderNode->restoreStates(dxContext, fStates); 232 | 233 | dxContext->VSSetShader(NULL, NULL, 0); 234 | dxContext->PSSetShader(NULL, NULL, 0); 235 | dxContext->GSSetShader(NULL, NULL, 0); 236 | dxContext->HSSetShader(NULL, NULL, 0); 237 | dxContext->DSSetShader(NULL, NULL, 0); 238 | 239 | dxContext->Release(); 240 | } 241 | } 242 | } 243 | } 244 | } 245 | 246 | MHWRender::DrawAPI dx11ShaderOverride::supportedDrawAPIs() const 247 | { 248 | return MHWRender::kDirectX11; 249 | } 250 | 251 | bool dx11ShaderOverride::isTransparent() 252 | { 253 | return (fShaderNode && fShaderNode->techniqueIsTransparent()); 254 | } 255 | 256 | bool dx11ShaderOverride::supportsAdvancedTransparency() const 257 | { 258 | return (fShaderNode && fShaderNode->techniqueSupportsAdvancedTransparency()); 259 | } 260 | 261 | bool dx11ShaderOverride::overridesDrawState() 262 | { 263 | return (fShaderNode && fShaderNode->techniqueOverridesDrawState()); 264 | } 265 | 266 | bool dx11ShaderOverride::rebuildAlways() 267 | { 268 | return !fShaderNode || fShaderNode->rebuildAlways(fGeometryVersionId); 269 | } 270 | 271 | double dx11ShaderOverride::boundingBoxExtraScale() const 272 | { 273 | if(fShaderNode != NULL) 274 | fBBoxExtraScale = fShaderNode->boundingBoxExtraScale(); 275 | 276 | return fBBoxExtraScale; 277 | } 278 | -------------------------------------------------------------------------------- /dx11ShaderOverride.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ShaderOverride_h_ 2 | #define _dx11ShaderOverride_h_ 3 | //- 4 | // Copyright 2011 Autodesk, Inc. All rights reserved. 5 | // 6 | // Use of this software is subject to the terms of the Autodesk license agreement 7 | // provided at the time of installation or download, or which otherwise 8 | // accompanies this software in either electronic or hard copy form. 9 | //+ 10 | 11 | #include 12 | #include "dx11Shader.h" 13 | 14 | 15 | class dx11ShaderOverride : public MHWRender::MPxShaderOverride 16 | { 17 | public: 18 | static MHWRender::MPxShaderOverride* Creator(const MObject& obj); 19 | 20 | virtual ~dx11ShaderOverride(); 21 | 22 | virtual MString initialize( const MInitContext& initContext,MInitFeedback& initFeedback); 23 | 24 | virtual void updateDG(MObject object); 25 | virtual void updateDevice(); 26 | virtual void endUpdate(); 27 | 28 | virtual bool handlesDraw(MHWRender::MDrawContext& context); 29 | virtual void activateKey(MHWRender::MDrawContext& context, const MString& key); 30 | virtual bool draw(MHWRender::MDrawContext& context,const MHWRender::MRenderItemList& renderItemList) const; 31 | virtual void terminateKey(MHWRender::MDrawContext& context, const MString& key); 32 | 33 | virtual MHWRender::DrawAPI supportedDrawAPIs() const; 34 | virtual bool isTransparent(); 35 | virtual bool supportsAdvancedTransparency() const; 36 | virtual bool overridesDrawState(); 37 | virtual bool rebuildAlways(); 38 | virtual double boundingBoxExtraScale() const; 39 | 40 | private: 41 | dx11ShaderOverride(const MObject& obj); 42 | 43 | // Current dx11Shader node associated with the shader override. 44 | dx11ShaderNode* fShaderNode; 45 | // version id which gets synced with match var on effect 46 | size_t fGeometryVersionId; 47 | 48 | // 49 | mutable double fBBoxExtraScale; 50 | 51 | // States values to save before and restore after executing the shader 52 | dx11ShaderNode::ContextStates fStates; 53 | }; 54 | 55 | #endif /* _dx11ShaderOverride_h_ */ 56 | -------------------------------------------------------------------------------- /dx11ShaderPluginMain.cpp: -------------------------------------------------------------------------------- 1 | //- 2 | // ========================================================================== 3 | // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved. 4 | // 5 | // Use of this software is subject to the terms of the Autodesk 6 | // license agreement provided at the time of installation or download, 7 | // or which otherwise accompanies this software in either electronic 8 | // or hard copy form. 9 | // ========================================================================== 10 | //+ 11 | 12 | #if _MSC_VER >= 1700 13 | #pragma warning( disable: 4005 ) 14 | #endif 15 | 16 | #include "dx11Shader.h" 17 | #include "dx11ShaderCmd.h" 18 | #include "dx11ShaderOverride.h" 19 | #include "dx11ShaderStrings.h" 20 | #include "dx11ConeAngleToHotspotConverter.h" 21 | #include "crackFreePrimitiveGenerator.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | static const MString sDX11ShaderRegistrantId("DX11ShaderRegistrantId"); 33 | 34 | MStatus initializePlugin( MObject obj ) 35 | // 36 | // Description: 37 | // this method is called when the plug-in is loaded into Maya. It 38 | // registers all of the services that this plug-in provides with 39 | // Maya. 40 | // 41 | // Arguments: 42 | // obj - a handle to the plug-in object (use MFnPlugin to access it) 43 | // 44 | { 45 | MFnPlugin plugin( obj, "Autodesk", "1.0", MApiVersion ); 46 | MString UserClassify = MString( "shader/surface/utility:drawdb/shader/surface/dx11Shader" ); 47 | 48 | // Register string resources 49 | // 50 | CHECK_MSTATUS( plugin.registerUIStrings( dx11ShaderStrings::registerMStringResources, "dx11ShaderInitStrings" ) ); 51 | 52 | // Don't initialize swatches in batch mode 53 | if (MGlobal::mayaState() != MGlobal::kBatch) 54 | { 55 | static MString swatchName("dx11ShaderRenderSwatchGen"); 56 | MSwatchRenderRegister::registerSwatchRender(swatchName, MHWShaderSwatchGenerator::createObj ); 57 | UserClassify = MString( "shader/surface/utility/:drawdb/shader/surface/dx11Shader:swatch/"+swatchName ); 58 | } 59 | 60 | // Run MEL script for user interface initialization. 61 | if (MGlobal::mayaState() == MGlobal::kInteractive) 62 | { 63 | MString sCmd = "evalDeferred \"source \\\"dx11Shader_initUI.mel\\\"\""; 64 | MGlobal::executeCommand( sCmd ); 65 | } 66 | 67 | CHECK_MSTATUS( plugin.registerNode("dx11Shader", 68 | dx11ShaderNode::typeId(), 69 | dx11ShaderNode::creator, 70 | dx11ShaderNode::initialize, 71 | MPxNode::kHardwareShader, 72 | &UserClassify)); 73 | 74 | CHECK_MSTATUS( plugin.registerNode( "coneAngleToHotspotConverter", 75 | dx11ConeAngleToHotspotConverter::typeId(), 76 | dx11ConeAngleToHotspotConverter::creator, 77 | dx11ConeAngleToHotspotConverter::initialize )); 78 | 79 | CHECK_MSTATUS( plugin.registerCommand("dx11Shader", 80 | dx11ShaderCmd::creator, 81 | dx11ShaderCmd::newSyntax)); 82 | 83 | // Register a shader override for this node 84 | CHECK_MSTATUS( 85 | MHWRender::MDrawRegistry::registerShaderOverrideCreator( 86 | "drawdb/shader/surface/dx11Shader", 87 | sDX11ShaderRegistrantId, 88 | dx11ShaderOverride::Creator)); 89 | 90 | // Register the vertex mutators with Maya 91 | // 92 | CHECK_MSTATUS( 93 | MHWRender::MDrawRegistry::registerIndexBufferMutator("PNAEN18", CrackFreePrimitiveGenerator::createCrackFreePrimitiveGenerator18)); 94 | 95 | CHECK_MSTATUS( 96 | MHWRender::MDrawRegistry::registerIndexBufferMutator("PNAEN9", CrackFreePrimitiveGenerator::createCrackFreePrimitiveGenerator9)); 97 | 98 | // Add and manage default plugin user pref: 99 | MGlobal::executeCommandOnIdle("dx11ShaderCreateUI"); 100 | 101 | // Register dx11Shader to filePathEditor 102 | MStatus status = MGlobal::executeCommand("filePathEditor -registerType \"dx11Shader.shader\" -typeLabel \"DX11Shader\" -temporary"); 103 | if (!status) { 104 | MString nodeAttr("dx11Shader.shader"); 105 | MString errorString = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorRegisterNodeType, nodeAttr ); 106 | MGlobal::displayWarning( errorString ); 107 | } 108 | 109 | return MStatus::kSuccess; 110 | } 111 | 112 | MStatus uninitializePlugin( MObject obj) 113 | // 114 | // Description: 115 | // this method is called when the plug-in is unloaded from Maya. It 116 | // deregisters all of the services that it was providing. 117 | // 118 | // Arguments: 119 | // obj - a handle to the plug-in object (use MFnPlugin to access it) 120 | // 121 | { 122 | MStatus status; 123 | MFnPlugin plugin( obj ); 124 | 125 | // Deregister our node types. 126 | // 127 | CHECK_MSTATUS( plugin.deregisterCommand( "dx11Shader" ) ); 128 | CHECK_MSTATUS( plugin.deregisterNode( dx11ShaderNode::typeId() )); 129 | CHECK_MSTATUS( plugin.deregisterNode( dx11ConeAngleToHotspotConverter::typeId() )); 130 | 131 | // Deregister the shader override 132 | // 133 | CHECK_MSTATUS( 134 | MHWRender::MDrawRegistry::deregisterShaderOverrideCreator( 135 | "drawdb/shader/surface/dx11Shader", 136 | sDX11ShaderRegistrantId)); 137 | 138 | // Deregister the vertex mutators 139 | // 140 | CHECK_MSTATUS(MHWRender::MDrawRegistry::deregisterIndexBufferMutator("PNAEN18")); 141 | CHECK_MSTATUS(MHWRender::MDrawRegistry::deregisterIndexBufferMutator("PNAEN9")); 142 | 143 | // Remove user pref UI: 144 | MGlobal::executeCommandOnIdle("dx11ShaderDeleteUI"); 145 | 146 | // Deregister dx11Shader from filePathEditor 147 | status = MGlobal::executeCommand("filePathEditor -deregisterType \"dx11Shader.shader\" -temporary"); 148 | if (!status) { 149 | MString nodeType("dx11Shader.shader"); 150 | MString errorString = dx11ShaderStrings::getString( dx11ShaderStrings::kErrorDeregisterNodeType, nodeType ); 151 | MGlobal::displayWarning( errorString ); 152 | } 153 | 154 | return MStatus::kSuccess; 155 | } 156 | 157 | 158 | -------------------------------------------------------------------------------- /dx11ShaderSemantics.cpp: -------------------------------------------------------------------------------- 1 | #include "dx11ShaderSemantics.h" 2 | 3 | namespace dx11ShaderSemantic 4 | { 5 | const char* kSTANDARDSGLOBAL = "STANDARDSGLOBAL"; 6 | const char* kUndefined = "Undefined"; 7 | 8 | const char* kWorld = "World"; 9 | const char* kWorldTranspose = "WorldTranspose"; 10 | const char* kWorldInverse = "WorldInverse"; 11 | const char* kWorldInverseTranspose = "WorldInverseTranspose"; 12 | 13 | const char* kView = "View"; 14 | const char* kViewTranspose = "ViewTranspose"; 15 | const char* kViewInverse = "ViewInverse"; 16 | const char* kViewInverseTranspose = "ViewInverseTranspose"; 17 | 18 | const char* kProjection = "Projection"; 19 | const char* kProjectionTranspose = "ProjectionTranspose"; 20 | const char* kProjectionInverse = "ProjectionInverse"; 21 | const char* kProjectionInverseTranspose = "ProjectionInverseTranspose"; 22 | 23 | const char* kWorldView = "WorldView"; 24 | const char* kWorldViewTranspose = "WorldViewTranspose"; 25 | const char* kWorldViewInverse = "WorldViewInverse"; 26 | const char* kWorldViewInverseTranspose = "WorldViewInverseTranspose"; 27 | 28 | const char* kViewProjection = "ViewProjection"; 29 | const char* kViewProjectionTranspose = "ViewProjectionTranspose"; 30 | const char* kViewProjectionInverse = "ViewProjectionInverse"; 31 | const char* kViewProjectionInverseTranspose = "ViewProjectionInverseTranspose"; 32 | 33 | const char* kWorldViewProjection = "WorldViewProjection"; 34 | const char* kWorldViewProjectionTranspose = "WorldViewProjectionTranspose"; 35 | const char* kWorldViewProjectionInverse = "WorldViewProjectionInverse"; 36 | const char* kWorldViewProjectionInverseTranspose = "WorldViewProjectionInverseTranspose"; 37 | 38 | const char* kViewDirection = "ViewDirection"; 39 | const char* kViewPosition = "ViewPosition"; 40 | const char* kLocalViewer = "LocalViewer"; 41 | 42 | const char* kViewportPixelSize = "ViewportPixelSize"; 43 | const char* kBackgroundColor = "BackgroundColor"; 44 | 45 | const char* kFrame = "Frame"; 46 | const char* kFrameNumber = "FrameNumber"; 47 | const char* kAnimationTime = "AnimationTime"; 48 | const char* kTime = "Time"; 49 | 50 | const char* kColor = "Color"; 51 | const char* kLightColor = "LightColor"; 52 | const char* kAmbient = "Ambient"; 53 | const char* kLightAmbientColor = "LightAmbientColor"; 54 | const char* kSpecular = "Specular"; 55 | const char* kLightSpecularColor = "LightSpecularColor"; 56 | const char* kDiffuse = "Diffuse"; 57 | const char* kLightDiffuseColor = "LightDiffuseColor"; 58 | const char* kNormal = "Normal"; 59 | const char* kBump = "Bump"; 60 | const char* kEnvironment = "Environment"; 61 | 62 | const char* kPosition = "Position"; 63 | const char* kAreaPosition0 = "AreaPosition0"; 64 | const char* kAreaPosition1 = "AreaPosition1"; 65 | const char* kAreaPosition2 = "AreaPosition2"; 66 | const char* kAreaPosition3 = "AreaPosition3"; 67 | const char* kDirection = "Direction"; 68 | 69 | const char* kTexCoord = "TexCoord"; 70 | const char* kTangent = "Tangent"; 71 | const char* kBinormal = "Binormal"; 72 | 73 | const char* kShadowMap = "ShadowMap"; 74 | const char* kShadowColor = "ShadowColor"; 75 | const char* kShadowFlag = "ShadowFlag"; 76 | const char* kShadowMapBias = "ShadowMapBias"; 77 | const char* kShadowMapMatrix = "ShadowMapMatrix"; 78 | const char* kShadowMapXForm = "ShadowMapXForm"; 79 | const char* kStandardsGlobal = "StandardsGlobal"; 80 | 81 | // Used to determine the type of a light parameter 82 | const char* kLightEnable = "LightEnable"; 83 | const char* kLightIntensity = "LightIntensity"; 84 | const char* kLightFalloff = "LightFalloff"; 85 | const char* kFalloff = "Falloff"; 86 | const char* kHotspot = "Hotspot"; 87 | const char* kLightType = "LightType"; 88 | const char* kDecayRate = "DecayRate"; 89 | 90 | const char* kLightRange = "LightRange"; 91 | const char* kLightAttenuation0 = "LightAttenuation0"; 92 | const char* kLightAttenuation1 = "LightAttenuation1"; 93 | const char* kLightAttenuation2 = "LightAttenuation2"; 94 | const char* kLightTheta = "LightTheta"; 95 | const char* kLightPhi = "LightPhi"; 96 | 97 | const char* kTranspDepthTexture = "transpdepthtexture"; 98 | const char* kOpaqueDepthTexture = "opaquedepthtexture"; 99 | 100 | //-------------------------- 101 | // Maya custom semantics 102 | 103 | // Define a boolean parameter to flag for swatch rendering 104 | const char* kMayaSwatchRender = "MayaSwatchRender"; 105 | 106 | // Define a float parameter to use to control the bounding box extra scale 107 | const char* kBboxExtraScale = "BoundingBoxExtraScale"; 108 | 109 | // Define a float parameter to use to check for transparency flag 110 | // Used in collaboration with the kIsTransparent annotation 111 | const char* kOpacity = "Opacity"; 112 | 113 | // Define a boolean parameter for full screen gamma correction 114 | const char* kMayaGammaCorrection = "MayaGammaCorrection"; 115 | } 116 | 117 | namespace dx11ShaderAnnotation 118 | { 119 | // Used to groups multiple parameters in a single 120 | // collapsible panel in the attribute editor. 121 | const char* kUIGroup = "UIGroup"; 122 | 123 | // Used for the short/long/nice name of a parameter 124 | // in the attribute editor. 125 | const char* kUIName = "UIName"; 126 | 127 | // Used to populate a dropdown menu when a 128 | // parameter is shown in the attribute editor. 129 | const char* kUIFieldNames = "UIFieldNames"; 130 | 131 | // Used to make sure all parameters appear in a predictable 132 | // sequence in the attribute editor. 133 | const char* kUIOrder = "UIOrder"; 134 | 135 | // These annotations control the visibility of a paramerer in the 136 | // attribute editor. 137 | const char* kSasUiVisible = "SasUiVisible"; 138 | const char* kUIType = "UIType"; 139 | const char* kUIWidget = "UIWidget"; 140 | 141 | // These annotations control the numeric range of a slider. 142 | const char* kSasUiMin = "SasUiMin"; 143 | const char* kUIMin = "UIMin"; 144 | const char* kuimin = "uimin"; 145 | const char* kSasUiMax = "SasUiMax"; 146 | const char* kUIMax = "UIMax"; 147 | const char* kuimax = "uimax"; 148 | const char* kSasUiSoftMin = "SasUiSoftMin"; 149 | const char* kUISoftMin = "UISoftMin"; 150 | const char* kuisoftmin = "uisoftmin"; 151 | const char* kSasUiSoftMax = "SasUiSoftMax"; 152 | const char* kUISoftMax = "UISoftMax"; 153 | const char* kuisoftmax = "uisoftmax"; 154 | 155 | // These annotations are used to get the default file to assign to 156 | // a texture resource. 157 | const char* kResourceName = "ResourceName"; 158 | const char* kSasResourceAddress = "SasResourceAddress"; 159 | 160 | // These annotations are used to determine the type of a 161 | // a texture resource. 162 | const char* kTextureType = "TextureType"; 163 | const char* kResourceType = "ResourceType"; 164 | 165 | // Used to convert from DX to Maya space 166 | const char* kSpace = "Space"; 167 | 168 | // Used to determine the semantic of a parameter 169 | const char* kSasBindAddress = "SasBindAddress"; 170 | const char* kSasUiControl = "SasUiControl"; 171 | 172 | // Used to determine the light type of a parameter 173 | const char* kObject = "Object"; 174 | 175 | //-------------------------- 176 | // Maya custom annotations 177 | 178 | // Technique annotations 179 | 180 | // Define the required index buffer generator to use for the technique 181 | const char* kIndexBufferType = "index_buffer_type"; 182 | 183 | // Define the mipmap levels to load/generate for textures used by the technique 184 | const char* kTextureMipmaplevels = "texture_mipmaplevels"; 185 | 186 | // Define if the technique should follow the Maya transparent object rendering or is self-managed (multi-passes) 187 | const char* kOverridesDrawState = "overridesDrawState"; 188 | 189 | // Define how the technique handles transparency 190 | const char* kIsTransparent = "isTransparent"; 191 | // Describe a condition that will be converted to a MEL procedure 192 | const char* kTransparencyTest = "transparencyTest"; 193 | // Describe whether the technique supports advanced transparency. 194 | const char* kSupportsAdvancedTransparency = "supportsAdvancedTransparency"; 195 | 196 | // Texture annotations 197 | 198 | // Define the mipmap levels to load/generate for the texture 199 | const char* kMipmaplevels = "mipmaplevels"; 200 | 201 | // Allow the shader writer to force the variable name to become the attribute name, even if UIName annotation is used 202 | const char* kVariableNameAsAttributeName = "VariableNameAsAttributeName"; 203 | } 204 | 205 | namespace dx11ShaderSemanticValue 206 | { 207 | // Custom semantic values used by the customPrimitiveGenerator plugin 208 | const char* kCustomPrimitiveTest = "customPrimitiveTest"; 209 | const char* kCustomPositionStream = "customPositionStream"; 210 | const char* kCustomNormalStream = "customNormalStream"; 211 | } 212 | 213 | namespace dx11ShaderAnnotationValue 214 | { 215 | const char* kNone = "None"; 216 | 217 | // Supported values for kTextureType and kResourceType annotations. 218 | const char* k1D = "1D"; 219 | const char* k2D = "2D"; 220 | const char* k3D = "3D"; 221 | const char* kCube = "Cube"; 222 | 223 | // Supported values for the kSpace annotation 224 | const char* kObject = "Object"; 225 | const char* kWorld = "World"; 226 | const char* kView = "View"; 227 | const char* kCamera = "Camera"; 228 | 229 | // Supported values for the kSasBindAddress annotation 230 | const char* kSas_Skeleton_MeshToJointToWorld_0_ = "Sas.Skeleton.MeshToJointToWorld[0]"; 231 | const char* kSas_Camera_WorldToView = "Sas.Camera.WorldToView"; 232 | const char* kSas_Camera_Projection = "Sas.Camera.Projection"; 233 | const char* kSas_Time_Now = "Sas.Time.Now"; 234 | const char* k_Position = ".Position"; 235 | const char* k_Direction = ".Direction"; 236 | const char* k_Directional = ".Directional"; 237 | 238 | // Supported value for the kSasUiControl annotation 239 | const char* kColorPicker = "ColorPicker"; 240 | 241 | // Used to try to determine an unknown semantic 242 | const char* kPosition = "Position"; 243 | const char* kDirection = "Direction"; 244 | const char* kColor = "Color"; 245 | const char* kColour = "Colour"; 246 | const char* kDiffuse = "Diffuse"; 247 | const char* kSpecular = "Specular"; 248 | const char* kAmbient = "Ambient"; 249 | 250 | // Supported values for the kObject annotation 251 | const char* kLight = "Light"; 252 | const char* kLamp = "Lamp"; 253 | const char* kPoint = "Point"; 254 | const char* kSpot = "Spot"; 255 | const char* kDirectional = "Directional"; 256 | } 257 | 258 | 259 | //- 260 | // Copyright 2012 Autodesk, Inc. All rights reserved. 261 | // 262 | // Use of this software is subject to the terms of the Autodesk license agreement 263 | // provided at the time of installation or download, or which otherwise 264 | // accompanies this software in either electronic or hard copy form. 265 | //+ 266 | -------------------------------------------------------------------------------- /dx11ShaderSemantics.h: -------------------------------------------------------------------------------- 1 | #ifndef __dx11ShaderSemantics_h__ 2 | #define __dx11ShaderSemantics_h__ 3 | 4 | namespace dx11ShaderSemantic 5 | { 6 | extern const char* kSTANDARDSGLOBAL; 7 | extern const char* kUndefined; 8 | 9 | extern const char* kWorld; 10 | extern const char* kWorldTranspose; 11 | extern const char* kWorldInverse; 12 | extern const char* kWorldInverseTranspose; 13 | 14 | extern const char* kView; 15 | extern const char* kViewTranspose; 16 | extern const char* kViewInverse; 17 | extern const char* kViewInverseTranspose; 18 | 19 | extern const char* kProjection; 20 | extern const char* kProjectionTranspose; 21 | extern const char* kProjectionInverse; 22 | extern const char* kProjectionInverseTranspose; 23 | 24 | extern const char* kWorldView; 25 | extern const char* kWorldViewTranspose; 26 | extern const char* kWorldViewInverse; 27 | extern const char* kWorldViewInverseTranspose; 28 | 29 | extern const char* kViewProjection; 30 | extern const char* kViewProjectionTranspose; 31 | extern const char* kViewProjectionInverse; 32 | extern const char* kViewProjectionInverseTranspose; 33 | 34 | extern const char* kWorldViewProjection; 35 | extern const char* kWorldViewProjectionTranspose; 36 | extern const char* kWorldViewProjectionInverse; 37 | extern const char* kWorldViewProjectionInverseTranspose; 38 | 39 | extern const char* kViewDirection; 40 | extern const char* kViewPosition; 41 | extern const char* kLocalViewer; 42 | 43 | extern const char* kViewportPixelSize; 44 | extern const char* kBackgroundColor; 45 | 46 | extern const char* kFrame; 47 | extern const char* kFrameNumber; 48 | extern const char* kAnimationTime; 49 | extern const char* kTime; 50 | 51 | extern const char* kColor; 52 | extern const char* kLightColor; 53 | extern const char* kAmbient; 54 | extern const char* kLightAmbientColor; 55 | extern const char* kSpecular; 56 | extern const char* kLightSpecularColor; 57 | extern const char* kDiffuse; 58 | extern const char* kLightDiffuseColor; 59 | extern const char* kNormal; 60 | extern const char* kBump; 61 | extern const char* kEnvironment; 62 | 63 | extern const char* kPosition; 64 | extern const char* kAreaPosition0; 65 | extern const char* kAreaPosition1; 66 | extern const char* kAreaPosition2; 67 | extern const char* kAreaPosition3; 68 | extern const char* kDirection; 69 | 70 | extern const char* kTexCoord; 71 | extern const char* kTangent; 72 | extern const char* kBinormal; 73 | 74 | extern const char* kShadowMap; 75 | extern const char* kShadowColor; 76 | extern const char* kShadowFlag; 77 | extern const char* kShadowMapBias; 78 | extern const char* kShadowMapMatrix; 79 | extern const char* kShadowMapXForm; 80 | extern const char* kStandardsGlobal; 81 | 82 | extern const char* kLightEnable; 83 | extern const char* kLightIntensity; 84 | extern const char* kLightFalloff; 85 | extern const char* kFalloff; 86 | extern const char* kHotspot; 87 | extern const char* kLightType; 88 | extern const char* kDecayRate; 89 | 90 | extern const char* kLightRange; 91 | extern const char* kLightAttenuation0; 92 | extern const char* kLightAttenuation1; 93 | extern const char* kLightAttenuation2; 94 | extern const char* kLightTheta; 95 | extern const char* kLightPhi; 96 | 97 | extern const char* kTranspDepthTexture; 98 | extern const char* kOpaqueDepthTexture; 99 | 100 | // Maya custom semantics 101 | extern const char* kMayaSwatchRender; 102 | extern const char* kBboxExtraScale; 103 | extern const char* kOpacity; 104 | extern const char* kMayaGammaCorrection; 105 | } 106 | 107 | namespace dx11ShaderAnnotation 108 | { 109 | extern const char* kUIGroup; 110 | extern const char* kUIName; 111 | extern const char* kUIFieldNames; 112 | extern const char* kUIOrder; 113 | 114 | extern const char* kSasUiVisible; 115 | extern const char* kUIType; 116 | extern const char* kUIWidget; 117 | 118 | extern const char* kSasUiMin; 119 | extern const char* kUIMin; 120 | extern const char* kuimin; 121 | extern const char* kSasUiMax; 122 | extern const char* kUIMax; 123 | extern const char* kuimax; 124 | extern const char* kSasUiSoftMin; 125 | extern const char* kUISoftMin; 126 | extern const char* kuisoftmin; 127 | extern const char* kSasUiSoftMax; 128 | extern const char* kUISoftMax; 129 | extern const char* kuisoftmax; 130 | 131 | extern const char* kResourceName; 132 | extern const char* kSasResourceAddress; 133 | extern const char* kTextureType; 134 | extern const char* kResourceType; 135 | 136 | extern const char* kSpace; 137 | 138 | extern const char* kSasBindAddress; 139 | 140 | extern const char* kSasUiControl; 141 | 142 | extern const char* kObject; 143 | 144 | // Maya custom annotations 145 | extern const char* kIndexBufferType; 146 | extern const char* kTextureMipmaplevels; 147 | extern const char* kMipmaplevels; 148 | extern const char* kOverridesDrawState; 149 | extern const char* kIsTransparent; 150 | extern const char* kTransparencyTest; 151 | extern const char* kSupportsAdvancedTransparency; 152 | extern const char* kVariableNameAsAttributeName; 153 | } 154 | 155 | namespace dx11ShaderSemanticValue 156 | { 157 | extern const char* kCustomPrimitiveTest; 158 | extern const char* kCustomPositionStream; 159 | extern const char* kCustomNormalStream; 160 | } 161 | 162 | namespace dx11ShaderAnnotationValue 163 | { 164 | extern const char* kNone; 165 | 166 | extern const char* k1D; 167 | extern const char* k2D; 168 | extern const char* k3D; 169 | extern const char* kCube; 170 | 171 | extern const char* kObject; 172 | extern const char* kWorld; 173 | extern const char* kView; 174 | extern const char* kCamera; 175 | 176 | extern const char* kSas_Skeleton_MeshToJointToWorld_0_; 177 | extern const char* kSas_Camera_WorldToView; 178 | extern const char* kSas_Camera_Projection; 179 | extern const char* kSas_Time_Now; 180 | extern const char* k_Position; 181 | extern const char* k_Direction; 182 | extern const char* k_Directional; 183 | 184 | extern const char* kColorPicker; 185 | 186 | extern const char* kPosition; 187 | extern const char* kDirection; 188 | extern const char* kColor; 189 | extern const char* kColour; 190 | extern const char* kDiffuse; 191 | extern const char* kSpecular; 192 | extern const char* kAmbient; 193 | 194 | extern const char* kLight; 195 | extern const char* kLamp; 196 | extern const char* kPoint; 197 | extern const char* kSpot; 198 | extern const char* kDirectional; 199 | } 200 | 201 | 202 | #endif 203 | 204 | //- 205 | // Copyright 2012 Autodesk, Inc. All rights reserved. 206 | // 207 | // Use of this software is subject to the terms of the Autodesk license agreement 208 | // provided at the time of installation or download, or which otherwise 209 | // accompanies this software in either electronic or hard copy form. 210 | //+ 211 | -------------------------------------------------------------------------------- /dx11ShaderStrings.cpp: -------------------------------------------------------------------------------- 1 | #include "dx11ShaderStrings.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace dx11ShaderStrings 8 | { 9 | #define kPluginId "dx11Shader" 10 | 11 | // dx11Shader_initUI.mel 12 | const MStringResourceId kReloadTool ( kPluginId, "kReloadTool", MString( "Reload" ) ); 13 | const MStringResourceId kReloadAnnotation ( kPluginId, "kReloadAnnotation", MString( "Reload fx file" ) ); 14 | const MStringResourceId kEditTool ( kPluginId, "kEditTool", MString( "Edit" ) ); 15 | const MStringResourceId kEditAnnotationWIN ( kPluginId, "kEditAnnotationWIN", MString( "Edit with application associated with fx file" ) ); 16 | const MStringResourceId kEditAnnotationMAC ( kPluginId, "kEditAnnotationMAC", MString( "Edit fx file with TextEdit" ) ); 17 | const MStringResourceId kEditAnnotationLNX ( kPluginId, "kEditAnnotationLNX", MString( "Edit fx file with your editor" ) ); 18 | const MStringResourceId kEditCommandLNX ( kPluginId, "kEditCommandLNX", MString( "Please set the command before using this feature." ) ); 19 | const MStringResourceId kNiceNodeName ( kPluginId, "kNiceNodeName", MString( "DirectX 11 Shader" ) ); 20 | 21 | // AEdx11ShaderTemplate.mel 22 | const MStringResourceId kShaderFile ( kPluginId, "kShaderFile", MString( "Shader File" ) ); 23 | const MStringResourceId kShader ( kPluginId, "kShader", MString( "Shader" ) ); 24 | const MStringResourceId kTechnique ( kPluginId, "kTechnique", MString( "Technique" ) ); 25 | const MStringResourceId kTechniqueTip ( kPluginId, "kTechniqueTip", MString( "Select among the rendering techniques defined in the fx file." ) ); 26 | const MStringResourceId kLightBinding ( kPluginId, "kLightBinding", MString( "Light Binding" ) ); 27 | const MStringResourceId kLightConnectionNone ( kPluginId, "kLightConnectionNone", MString( "Use Shader Settings" ) ); 28 | const MStringResourceId kLightConnectionImplicit ( kPluginId, "kLightConnectionImplicit", MString( "Automatic Bind" ) ); 29 | const MStringResourceId kLightConnectionImplicitNone( kPluginId, "kLightConnectionImplicitNone",MString( "none" ) ); 30 | const MStringResourceId kLightConnectionNoneTip ( kPluginId, "kLightConnectionNoneTip", MString( "Ignores Maya lights and uses the settings in the fx file." ) ); 31 | const MStringResourceId kLightConnectionImplicitTip ( kPluginId, "kLightConnectionImplicitTip", MString( "Maya will automatically bind scene lights and parameters to the lights defined in the fx file." ) ); 32 | const MStringResourceId kLightConnectionExplicitTip ( kPluginId, "kLightConnectionExplicitTip", MString( "Explicitly binds a Maya scene light and it's parameters to a light defined in the fx file." ) ); 33 | const MStringResourceId kShaderParameters ( kPluginId, "kShaderParameters", MString( "Parameters" ) ); 34 | const MStringResourceId kSurfaceData ( kPluginId, "kSurfaceData", MString( "Surface Data" ) ); 35 | const MStringResourceId kDiagnostics ( kPluginId, "kDiagnostics", MString( "Diagnostics" ) ); 36 | const MStringResourceId kNoneDefined ( kPluginId, "kNoneDefined", MString( "None defined" ) ); 37 | const MStringResourceId kEffectFiles ( kPluginId, "kEffectFiles", MString( "Effect Files" ) ); 38 | const MStringResourceId kAmbient ( kPluginId, "kAmbient", MString( "Ambient" ) ); 39 | 40 | const MStringResourceId kActionChoose ( kPluginId, "kActionChoose", MString( "Choose button action:" ) ); 41 | const MStringResourceId kActionEdit ( kPluginId, "kActionEdit", MString( "Edit the action definition" ) ); 42 | const MStringResourceId kActionNew ( kPluginId, "kActionNew", MString( "New action..." ) ); 43 | const MStringResourceId kActionNewAnnotation ( kPluginId, "kActionNewAnnotation", MString( "Add a new action to this menu" ) ); 44 | const MStringResourceId kActionNothing ( kPluginId, "kActionNothing", MString( "(nothing)" ) ); 45 | const MStringResourceId kActionNothingAnnotation ( kPluginId, "kActionNothingAnnotation", MString( "Button does nothing; not assigned." ) ); 46 | const MStringResourceId kActionNotAssigned ( kPluginId, "kActionNotAssigned", MString( "LMB: Does nothing; not assigned. RMB: Choose what this button should do." ) ); 47 | const MStringResourceId kActionEmptyCommand ( kPluginId, "kActionEmptyCommand", MString( "LMB: Does nothing; empty command. RMB: Choose what this button should do." ) ); 48 | 49 | const MStringResourceId kActionEditorTitle ( kPluginId, "kActionEditorTitle", MString( "dx11Shader Tool Button Editor" ) ); 50 | const MStringResourceId kActionEditorName ( kPluginId, "kActionEditorName", MString( "Name" ) ); 51 | const MStringResourceId kActionEditorImageFile ( kPluginId, "kActionEditorImageFile", MString( "Image File" ) ); 52 | const MStringResourceId kActionEditorDescription ( kPluginId, "kActionEditorDescription", MString( "Description" ) ); 53 | const MStringResourceId kActionEditorCommands ( kPluginId, "kActionEditorCommands", MString( "Commands" ) ); 54 | const MStringResourceId kActionEditorInsertVariable ( kPluginId, "kActionEditorInsertVariable", MString( "Insert variable:" ) ); 55 | const MStringResourceId kActionEditorSave ( kPluginId, "kActionEditorSave", MString( "Save" ) ); 56 | const MStringResourceId kActionEditorCreate ( kPluginId, "kActionEditorCreate", MString( "Create" ) ); 57 | const MStringResourceId kActionEditorDelete ( kPluginId, "kActionEditorDelete", MString( "Delete" ) ); 58 | const MStringResourceId kActionEditorClose ( kPluginId, "kActionEditorClose", MString( "Close" ) ); 59 | 60 | //dx11ShaderCreateUI.mel 61 | const MStringResourceId kPrefSavePrefsOrNotMsg ( kPluginId, "kPrefSavePrefsOrNotMsg", MString( "The dx11Shader plug-in is about to refresh preferences windows. Save your changes in the preferences window?" ) ); 62 | const MStringResourceId kPrefSaveMsg ( kPluginId, "kPrefSaveMsg", MString( "Save Preferences" ) ); 63 | const MStringResourceId kPrefFileOpen ( kPluginId, "kPrefFileOpen", MString( "Open" ) ); 64 | const MStringResourceId kPrefDefaultEffectFile ( kPluginId, "kPrefDefaultEffectFile", MString( "Default effects file" ) ); 65 | const MStringResourceId kPrefDx11ShaderPanel ( kPluginId, "kPrefDx11ShaderPanel", MString( "DX 11 Shader Preferences" ) ); 66 | const MStringResourceId kPrefDx11ShaderTab ( kPluginId, "kPrefDx11ShaderTab", MString( " DX 11 Shader" ) ); 67 | 68 | //dx11ShaderCompileHelper 69 | const MStringResourceId kErrorEffectCompile ( kPluginId, "kErrorEffectCompile", MString( "Effect from file compile errors (^1s) {\n^2s\n}\n" ) ); 70 | const MStringResourceId kErrorEffectBuffer ( kPluginId, "kErrorEffectBuffer", MString( "Effect from buffer creation errors: {\n^1s\n}\n" ) ); 71 | const MStringResourceId kErrorFileNotFound ( kPluginId, "kErrorFileNotFound", MString( "Effect file \"^1s\" not found." ) ); 72 | const MStringResourceId kErrorInvalidEffectFile ( kPluginId, "kErrorInvalidEffectFile", MString( "Invalid effect file \"^1s\"." ) ); 73 | const MStringResourceId kErrorAbsolutePathNotFound ( kPluginId, "kErrorAbsolutePathNotFound", MString( "Effect file \"^1s\" not found, using \"^2s\" instead.\n" ) ); 74 | 75 | //dx11ShaderNode 76 | const MStringResourceId kErrorIndexVaryingParameter ( kPluginId, "kErrorIndexVaryingParameter", MString( "Unsupported index on varying parameter ^1s. Index will be interpreted as 0\n" ) ); 77 | const MStringResourceId kErrorVertexRequirement ( kPluginId, "kErrorVertexRequirement", MString( "Unsupported per vertex requirement for ^1s^2s. The vector size should be between ^3s and ^4s, the effect requires ^5s\n" ) ); 78 | const MStringResourceId kWarningVertexRequirement ( kPluginId, "kWarningVertexRequirement", MString( "Per vertex requirement for ^1s. The vector size maya provides is ^2s, the effect requires ^3s\n" ) ); 79 | 80 | const MStringResourceId kErrorNoValidTechniques ( kPluginId, "kErrorNoValidTechniques", MString( "Cannot initialize techniques. Effect has no valid techniques.\n" ) ); 81 | const MStringResourceId kErrorSetTechniqueByName ( kPluginId, "kErrorSetTechniqueByName", MString( "Failed to set technique. Technique ^1s does not exist on effect.\n" ) ); 82 | const MStringResourceId kErrorSetTechniqueByIndex ( kPluginId, "kErrorSetTechniqueByIndex", MString( "Failed to set technique. Technique #^1s does not exist on effect.\n" ) ); 83 | const MStringResourceId kErrorIsTransparentOpacity ( kPluginId, "kErrorIsTransparentOpacity", MString( "Technique with isTransparent == 2 annotation must have one parameter with Opacity semantics.\n" ) ); 84 | const MStringResourceId kErrorUnknownIsTransparent ( kPluginId, "kErrorUnknownIsTransparent", MString( "Technique has unknown isTransparent annotation value ( 0: Opaque, 1: Transparent, 2: Use opacity semantics ).\n" ) ); 85 | const MStringResourceId kErrorSetPass ( kPluginId, "kErrorSetPass", MString( "Failed to set pass. Pass #^1s does not exist on technique: ^2s.\n" ) ); 86 | const MStringResourceId kErrorRegisterNodeType ( kPluginId, "kErrorRegisterNodeType", MString( "Failed to register ^1s to filePathEditor" ) ); 87 | const MStringResourceId kErrorDeregisterNodeType ( kPluginId, "kErrorDeregisterNodeType", MString( "Failed to deregister ^1s from filePathEditor" ) ); 88 | 89 | const MStringResourceId kErrorLog ( kPluginId, "kErrorLog", MString( "errors :\n^1s" ) ); 90 | const MStringResourceId kWarningLog ( kPluginId, "kWarningLog", MString( "warnings :\n^1s" ) ); 91 | 92 | //dx11ShaderCmd 93 | const MStringResourceId kInvalidDx11ShaderNode ( kPluginId, "kInvalidDx11ShaderNode", MString( "Invalid dx11Shader node: ^1s" ) ); 94 | const MStringResourceId kUnknownConnectableLight ( kPluginId, "kUnknownConnectableLight", MString( "Unknown connectable light: ^1s" ) ); 95 | const MStringResourceId kUnknownSceneObject ( kPluginId, "kUnknownSceneObject", MString( "Unknown scene object: ^1s" ) ); 96 | const MStringResourceId kUnknownUIGroup ( kPluginId, "kUnknownUIGroup", MString( "Unknown UI group: ^1s" ) ); 97 | const MStringResourceId kNotALight ( kPluginId, "kNotALight", MString( "Not a light: ^1s" ) ); 98 | 99 | //dx11ShaderUniformParamBuilder 100 | const MStringResourceId kUnsupportedType ( kPluginId, "kUnsupportedType", MString( "Unsupported ^1s on parameter ^2s. Parameter will be ignored\n" ) ); 101 | const MStringResourceId kUnknowSemantic ( kPluginId, "kUnknowSemantic", MString( "Unrecognized semantic ^1s on parameter ^2s\n" ) ); 102 | const MStringResourceId kUnknowSpace ( kPluginId, "kUnknowSpace", MString( "Unrecognised space ^1s on parameter ^2s\n" ) ); 103 | const MStringResourceId kNoTextureType ( kPluginId, "kNoTextureType", MString( "No texture type provided for ^1s, assuming 2D\n" ) ); 104 | const MStringResourceId kUnknownTextureSemantic ( kPluginId, "kUnknownTextureSemantic", MString( "Unrecognised texture type semantic ^1s on parameter ^2s\n" ) ); 105 | 106 | const MStringResourceId kTypeStringVector ( kPluginId, "kTypeStringVector", MString( "string vector" ) ); 107 | const MStringResourceId kTypeBoolVector ( kPluginId, "kTypeBoolVector", MString( "bool vector" ) ); 108 | const MStringResourceId kTypeIntVector ( kPluginId, "kTypeIntVector", MString( "int vector" ) ); 109 | const MStringResourceId kTypeIntUInt8 ( kPluginId, "kTypeIntUInt8", MString( "uint8" ) ); 110 | const MStringResourceId kTypeDouble ( kPluginId, "kTypeDouble", MString( "double" ) ); 111 | const MStringResourceId kTypeTextureArray ( kPluginId, "kTypeTextureArray", MString( "texture array" ) ); 112 | 113 | //dx11ConeAngleToHotspotConverter 114 | const MStringResourceId kErrorConeAngle ( kPluginId, "kErrorConeAngle", MString( "ERROR getting ConeAngle data" ) ); 115 | const MStringResourceId kErrorPenumbraAngle ( kPluginId, "kErrorPenumbraAngle", MString( "ERROR getting PenumbraAngle data" ) ); 116 | } 117 | 118 | 119 | // Register all strings 120 | // 121 | MStatus dx11ShaderStrings::registerMStringResources(void) 122 | { 123 | // dx11Shader_initUI.mel 124 | MStringResource::registerString( kReloadTool ); 125 | MStringResource::registerString( kReloadAnnotation ); 126 | MStringResource::registerString( kEditTool ); 127 | MStringResource::registerString( kEditAnnotationWIN ); 128 | MStringResource::registerString( kEditAnnotationMAC ); 129 | MStringResource::registerString( kEditAnnotationLNX ); 130 | MStringResource::registerString( kEditCommandLNX ); 131 | MStringResource::registerString( kNiceNodeName ); 132 | 133 | // AEdx11ShaderTemplate.mel 134 | MStringResource::registerString( kShaderFile ); 135 | MStringResource::registerString( kShader ); 136 | MStringResource::registerString( kTechnique ); 137 | MStringResource::registerString( kTechniqueTip ); 138 | MStringResource::registerString( kLightBinding ); 139 | MStringResource::registerString( kLightConnectionNone ); 140 | MStringResource::registerString( kLightConnectionImplicit ); 141 | MStringResource::registerString( kLightConnectionImplicitNone ); 142 | MStringResource::registerString( kLightConnectionNoneTip ); 143 | MStringResource::registerString( kLightConnectionImplicitTip ); 144 | MStringResource::registerString( kLightConnectionExplicitTip ); 145 | MStringResource::registerString( kShaderParameters ); 146 | MStringResource::registerString( kSurfaceData ); 147 | MStringResource::registerString( kDiagnostics ); 148 | MStringResource::registerString( kNoneDefined ); 149 | MStringResource::registerString( kEffectFiles ); 150 | MStringResource::registerString( kAmbient ); 151 | 152 | MStringResource::registerString( kActionChoose ); 153 | MStringResource::registerString( kActionEdit ); 154 | MStringResource::registerString( kActionNew ); 155 | MStringResource::registerString( kActionNewAnnotation ); 156 | MStringResource::registerString( kActionNothing ); 157 | MStringResource::registerString( kActionNothingAnnotation ); 158 | MStringResource::registerString( kActionNotAssigned ); 159 | MStringResource::registerString( kActionEmptyCommand ); 160 | 161 | MStringResource::registerString( kActionEditorTitle ); 162 | MStringResource::registerString( kActionEditorName ); 163 | MStringResource::registerString( kActionEditorImageFile ); 164 | MStringResource::registerString( kActionEditorDescription ); 165 | MStringResource::registerString( kActionEditorCommands ); 166 | MStringResource::registerString( kActionEditorInsertVariable ); 167 | MStringResource::registerString( kActionEditorSave ); 168 | MStringResource::registerString( kActionEditorCreate ); 169 | MStringResource::registerString( kActionEditorDelete ); 170 | MStringResource::registerString( kActionEditorClose ); 171 | 172 | //dx11ShaderCreateUI.mel 173 | MStringResource::registerString( kPrefSavePrefsOrNotMsg ); 174 | MStringResource::registerString( kPrefSaveMsg ); 175 | MStringResource::registerString( kPrefFileOpen ); 176 | MStringResource::registerString( kPrefDefaultEffectFile ); 177 | MStringResource::registerString( kPrefDx11ShaderPanel ); 178 | MStringResource::registerString( kPrefDx11ShaderTab ); 179 | 180 | //dx11ShaderCompileHelper 181 | MStringResource::registerString( kErrorEffectCompile ); 182 | MStringResource::registerString( kErrorEffectBuffer ); 183 | MStringResource::registerString( kErrorFileNotFound ); 184 | MStringResource::registerString( kErrorAbsolutePathNotFound ); 185 | 186 | //dx11ShaderNode 187 | MStringResource::registerString( kErrorIndexVaryingParameter ); 188 | MStringResource::registerString( kErrorVertexRequirement ); 189 | MStringResource::registerString( kWarningVertexRequirement ); 190 | 191 | MStringResource::registerString( kErrorNoValidTechniques ); 192 | MStringResource::registerString( kErrorSetTechniqueByName ); 193 | MStringResource::registerString( kErrorSetTechniqueByIndex ); 194 | MStringResource::registerString( kErrorIsTransparentOpacity ); 195 | MStringResource::registerString( kErrorUnknownIsTransparent ); 196 | MStringResource::registerString( kErrorSetPass ); 197 | MStringResource::registerString( kErrorRegisterNodeType ); 198 | MStringResource::registerString( kErrorDeregisterNodeType ); 199 | 200 | MStringResource::registerString( kErrorLog ); 201 | MStringResource::registerString( kWarningLog ); 202 | 203 | //dx11ShaderCmd 204 | MStringResource::registerString( kInvalidDx11ShaderNode ); 205 | MStringResource::registerString( kUnknownConnectableLight ); 206 | MStringResource::registerString( kUnknownSceneObject ); 207 | MStringResource::registerString( kUnknownUIGroup ); 208 | MStringResource::registerString( kNotALight ); 209 | 210 | //dx11ShaderUniformParamBuilder 211 | MStringResource::registerString( kUnsupportedType ); 212 | MStringResource::registerString( kUnknowSemantic ); 213 | MStringResource::registerString( kUnknowSpace ); 214 | MStringResource::registerString( kNoTextureType ); 215 | MStringResource::registerString( kUnknownTextureSemantic ); 216 | 217 | MStringResource::registerString( kTypeStringVector ); 218 | MStringResource::registerString( kTypeBoolVector ); 219 | MStringResource::registerString( kTypeIntVector ); 220 | MStringResource::registerString( kTypeIntUInt8 ); 221 | MStringResource::registerString( kTypeDouble ); 222 | MStringResource::registerString( kTypeTextureArray ); 223 | 224 | //dx11ConeAngleToHotspotConverter 225 | MStringResource::registerString( kErrorConeAngle ); 226 | MStringResource::registerString( kErrorPenumbraAngle ); 227 | 228 | return MS::kSuccess; 229 | } 230 | 231 | MString dx11ShaderStrings::getString(const MStringResourceId &stringId) 232 | { 233 | MStatus status; 234 | return MStringResource::getString(stringId, status); 235 | } 236 | 237 | MString dx11ShaderStrings::getString(const MStringResourceId &stringId, const MString& arg) 238 | { 239 | MStringArray args; 240 | args.append(arg); 241 | return dx11ShaderStrings::getString(stringId, args); 242 | } 243 | 244 | MString dx11ShaderStrings::getString(const MStringResourceId &stringId, const MStringArray& args) 245 | { 246 | MString string; 247 | string.format( dx11ShaderStrings::getString(stringId), args); 248 | return string; 249 | } 250 | 251 | //- 252 | // Copyright 2012 Autodesk, Inc. All rights reserved. 253 | // 254 | // Use of this software is subject to the terms of the Autodesk license agreement 255 | // provided at the time of installation or download, or which otherwise 256 | // accompanies this software in either electronic or hard copy form. 257 | //+ 258 | -------------------------------------------------------------------------------- /dx11ShaderStrings.h: -------------------------------------------------------------------------------- 1 | #ifndef __dx11ShaderStrings_h__ 2 | #define __dx11ShaderStrings_h__ 3 | 4 | #include 5 | 6 | class MString; 7 | class MStringArray; 8 | 9 | namespace dx11ShaderStrings 10 | { 11 | // dx11Shader_initUI.mel 12 | extern const MStringResourceId kReloadTool; 13 | extern const MStringResourceId kReloadAnnotation; 14 | extern const MStringResourceId kEditTool; 15 | extern const MStringResourceId kEditAnnotationWIN; 16 | extern const MStringResourceId kEditAnnotationMAC; 17 | extern const MStringResourceId kEditAnnotationLNX; 18 | extern const MStringResourceId kEditCommandLNX; 19 | extern const MStringResourceId kNiceNodeName; 20 | 21 | // AEdx11ShaderTemplate.mel 22 | extern const MStringResourceId kShaderFile; 23 | extern const MStringResourceId kShader; 24 | extern const MStringResourceId kTechnique; 25 | extern const MStringResourceId kTechniqueTip; 26 | extern const MStringResourceId kLightBinding; 27 | extern const MStringResourceId kLightConnectionNone; 28 | extern const MStringResourceId kLightConnectionImplicit; 29 | extern const MStringResourceId kLightConnectionImplicitNone; 30 | extern const MStringResourceId kLightConnectionNoneTip; 31 | extern const MStringResourceId kLightConnectionImplicitTip; 32 | extern const MStringResourceId kLightConnectionExplicitTip; 33 | extern const MStringResourceId kShaderParameters; 34 | extern const MStringResourceId kSurfaceData; 35 | extern const MStringResourceId kDiagnostics; 36 | extern const MStringResourceId kNoneDefined; 37 | extern const MStringResourceId kEffectFiles; 38 | extern const MStringResourceId kAmbient; 39 | 40 | extern const MStringResourceId kActionChoose; 41 | extern const MStringResourceId kActionEdit; 42 | extern const MStringResourceId kActionNew; 43 | extern const MStringResourceId kActionNewAnnotation; 44 | extern const MStringResourceId kActionNothing; 45 | extern const MStringResourceId kActionNothingAnnotation; 46 | extern const MStringResourceId kActionNotAssigned; 47 | extern const MStringResourceId kActionEmptyCommand; 48 | 49 | extern const MStringResourceId kActionEditorTitle; 50 | extern const MStringResourceId kActionEditorName; 51 | extern const MStringResourceId kActionEditorImageFile; 52 | extern const MStringResourceId kActionEditorDescription; 53 | extern const MStringResourceId kActionEditorCommands; 54 | extern const MStringResourceId kActionEditorInsertVariable; 55 | extern const MStringResourceId kActionEditorSave; 56 | extern const MStringResourceId kActionEditorCreate; 57 | extern const MStringResourceId kActionEditorDelete; 58 | extern const MStringResourceId kActionEditorClose; 59 | 60 | //dx11ShaderCreateUI.mel 61 | extern const MStringResourceId kPrefSavePrefsOrNotMsg; 62 | extern const MStringResourceId kPrefSaveMsg; 63 | extern const MStringResourceId kPrefFileOpen; 64 | extern const MStringResourceId kPrefDefaultEffectFile; 65 | extern const MStringResourceId kPrefDx11ShaderPanel; 66 | extern const MStringResourceId kPrefDx11ShaderTab; 67 | 68 | //dx11ShaderCompileHelper 69 | extern const MStringResourceId kErrorEffectCompile; 70 | extern const MStringResourceId kErrorEffectBuffer; 71 | extern const MStringResourceId kErrorFileNotFound; 72 | extern const MStringResourceId kErrorInvalidEffectFile; 73 | extern const MStringResourceId kErrorAbsolutePathNotFound; 74 | 75 | //dx11ShaderNode 76 | extern const MStringResourceId kErrorIndexVaryingParameter; 77 | extern const MStringResourceId kErrorVertexRequirement; 78 | extern const MStringResourceId kWarningVertexRequirement; 79 | 80 | extern const MStringResourceId kErrorNoValidTechniques; 81 | extern const MStringResourceId kErrorSetTechniqueByName; 82 | extern const MStringResourceId kErrorSetTechniqueByIndex; 83 | extern const MStringResourceId kErrorIsTransparentOpacity; 84 | extern const MStringResourceId kErrorUnknownIsTransparent; 85 | extern const MStringResourceId kErrorSetPass; 86 | extern const MStringResourceId kErrorRegisterNodeType; 87 | extern const MStringResourceId kErrorDeregisterNodeType; 88 | 89 | extern const MStringResourceId kErrorLog; 90 | extern const MStringResourceId kWarningLog; 91 | 92 | //dx11ShaderCmd 93 | extern const MStringResourceId kInvalidDx11ShaderNode; 94 | extern const MStringResourceId kUnknownConnectableLight; 95 | extern const MStringResourceId kUnknownSceneObject; 96 | extern const MStringResourceId kUnknownUIGroup; 97 | extern const MStringResourceId kNotALight; 98 | 99 | //dx11ShaderUniformParamBuilder 100 | extern const MStringResourceId kUnsupportedType; 101 | extern const MStringResourceId kUnknowSemantic; 102 | extern const MStringResourceId kUnknowSpace; 103 | extern const MStringResourceId kNoTextureType; 104 | extern const MStringResourceId kUnknownTextureSemantic; 105 | 106 | extern const MStringResourceId kTypeStringVector; 107 | extern const MStringResourceId kTypeBoolVector; 108 | extern const MStringResourceId kTypeIntVector; 109 | extern const MStringResourceId kTypeIntUInt8; 110 | extern const MStringResourceId kTypeDouble; 111 | extern const MStringResourceId kTypeTextureArray; 112 | 113 | //dx11ConeAngleToHotspotConverter 114 | extern const MStringResourceId kErrorConeAngle; 115 | extern const MStringResourceId kErrorPenumbraAngle; 116 | 117 | // Register all strings 118 | MStatus registerMStringResources(void); 119 | 120 | MString getString(const MStringResourceId &stringId); 121 | MString getString(const MStringResourceId &stringId, const MString& arg); 122 | MString getString(const MStringResourceId &stringId, const MStringArray& args); 123 | } 124 | 125 | #endif 126 | 127 | //- 128 | // Copyright 2012 Autodesk, Inc. All rights reserved. 129 | // 130 | // Use of this software is subject to the terms of the Autodesk license agreement 131 | // provided at the time of installation or download, or which otherwise 132 | // accompanies this software in either electronic or hard copy form. 133 | //+ 134 | 135 | -------------------------------------------------------------------------------- /dx11ShaderUniformParamBuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef _dx11ShaderUniformParamBuilder_h_ 2 | #define _dx11ShaderUniformParamBuilder_h_ 3 | //- 4 | // ========================================================================== 5 | // Copyright 1995,2006,2008,2011 Autodesk, Inc. All rights reserved. 6 | // 7 | // Use of this software is subject to the terms of the Autodesk 8 | // license agreement provided at the time of installation or download, 9 | // or which otherwise accompanies this software in either electronic 10 | // or hard copy form. 11 | // ========================================================================== 12 | //+ 13 | #include 14 | 15 | // Includes for DX11 16 | #define WIN32_LEAN_AND_MEAN 17 | #include 18 | 19 | // for VS 2012, Win8 SDK includes DX sdk with some header removed 20 | #if _MSC_VER >= 1700 21 | #include 22 | #else 23 | #include 24 | #endif 25 | 26 | // To build against the DX SDK header use the following commented line 27 | //#include <../Samples/C++/Effects11/Inc/d3dx11effect.h> 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | class dx11ShaderNode; 34 | class MStringResourceId; 35 | 36 | class CUniformParameterBuilder 37 | { 38 | public: 39 | CUniformParameterBuilder(); 40 | 41 | 42 | void init(ID3DX11EffectVariable* inEffectVariable,dx11ShaderNode* inShader, int order); 43 | 44 | bool build(); 45 | 46 | bool isValidUniformParameter() 47 | {return mValidUniformParameter;} 48 | 49 | MUniformParameter& getParameter() 50 | {return mParam;} 51 | 52 | ID3DX11EffectVariable* getEffectVariable() 53 | {return mEffectVariable; } 54 | 55 | MString& getWarnings() 56 | {return mWarnings;} 57 | 58 | 59 | enum ELightParameterType 60 | { 61 | eUndefined, // 0 62 | eLightPosition, 63 | eLightDirection, 64 | eLightColor, 65 | eLightSpecularColor, 66 | eLightAmbientColor, // 5 67 | eLightDiffuseColor, 68 | eLightRange, 69 | eLightFalloff, 70 | eLightAttenuation0, 71 | eLightAttenuation1, // 10 72 | eLightAttenuation2, 73 | eLightTheta, 74 | eLightPhi, 75 | eLightShadowMap, 76 | eLightShadowMapBias, // 15 77 | eLightShadowColor, 78 | eLightShadowViewProj, 79 | eLightShadowOn, 80 | eLightIntensity, 81 | eLightHotspot, // 20 82 | eLightEnable, 83 | eLightType, 84 | eDecayRate, 85 | eLightAreaPosition0, 86 | eLightAreaPosition1, // 25 87 | eLightAreaPosition2, 88 | eLightAreaPosition3, 89 | 90 | // When updating this array, please keep the 91 | // strings in getLightParameterSemantic in sync. 92 | // Thanks! 93 | eLastParameterType, 94 | }; 95 | ELightParameterType getLightParameterType() 96 | {return mParamType;} 97 | 98 | // Get semantic string back from enum: 99 | static MString& getLightParameterSemantic(int lightParameterType); 100 | 101 | enum ELightType 102 | { 103 | eNotLight, 104 | eUndefinedLight, 105 | ePointLight, 106 | eSpotLight, 107 | eDirectionalLight, 108 | eAmbientLight, 109 | eAreaLight, 110 | }; 111 | 112 | ELightType getLightType() 113 | {return mLightType;} 114 | 115 | int getLightIndex() 116 | { return mLightIndex; } 117 | 118 | int getUIGroupIndex() 119 | { return mUIGroupIndex; } 120 | 121 | int getUIOrder() 122 | { return mUIOrder; } 123 | 124 | static bool compareUIOrder(CUniformParameterBuilder* a, CUniformParameterBuilder* b) 125 | {return (a->getUIOrder() < b->getUIOrder());} 126 | 127 | protected: 128 | 129 | 130 | bool getAnnotation(const char* name,LPCSTR& value); 131 | bool getAnnotation(const char* name,float& value); 132 | bool getAnnotation(const char* name,int& value); 133 | bool getBOOLAnnotation(const char* name,BOOL& value); 134 | ID3DX11EffectVariable* findAnnotationByName(ID3DX11EffectVariable *effectVariable, const char* name); 135 | 136 | int getLength() 137 | { 138 | int rows = mDescType.Rows; 139 | int columns = mDescType.Columns; 140 | return rows * columns; 141 | } 142 | 143 | bool setParameterValueFromEffect(); 144 | MUniformParameter::DataType convertType(); 145 | MUniformParameter::DataSemantic convertSpace( MUniformParameter::DataSemantic defaultSpace); 146 | void updateRangeFromAnnotation(); 147 | void updateUIVisibilityFromAnnotation(); 148 | MUniformParameter::DataSemantic convertSemantic(); 149 | void updateLightInfoFromSemantic(); 150 | 151 | 152 | void logUnsupportedTypeWarning(const MStringResourceId& typeId); 153 | void logUnrecognisedSemantic(const char* pSemantic); 154 | 155 | 156 | ID3DX11EffectVariable* mEffectVariable; 157 | dx11ShaderNode * mShader; 158 | D3DX11_EFFECT_VARIABLE_DESC mDesc; 159 | D3DX11_EFFECT_TYPE_DESC mDescType; 160 | MUniformParameter mParam; 161 | ELightParameterType mParamType; 162 | MString mWarnings; 163 | ELightType mLightType; 164 | int mLightIndex; 165 | int mUIGroupIndex; 166 | bool mValidUniformParameter; 167 | int mUIOrder; 168 | typedef std::map TAnnotationIndex; 169 | TAnnotationIndex mAnnotationIndex; 170 | }; 171 | 172 | 173 | #endif /* _dx11ShaderUniformParamBuilder_h_ */ 174 | -------------------------------------------------------------------------------- /dx11Shader_defaults.mel: -------------------------------------------------------------------------------- 1 | // requires maya "2013ff06"; 2 | startAttrPreset( "dx11Shader" ); 3 | // This procedural preset provides a way to get back to the default values from the effect file: 4 | if (`attributeExists "uniformParameters" $gAEAttrPresetCurrentTarget`) 5 | { 6 | // Get all the uniform parameters: 7 | string $dx11ShaderPresetUniformAttributes[] = `getAttr ($gAEAttrPresetCurrentTarget + ".uniformParameters")`; 8 | 9 | // We want to preset all leaf attributes, so we need to convert float2, float3, float4 and compound into leaf attributes: 10 | while (size($dx11ShaderPresetUniformAttributes)) 11 | { 12 | // Pop the first attribute: 13 | string $dx11ShaderPresetCurrentAttr = $dx11ShaderPresetUniformAttributes[0]; 14 | stringArrayRemoveAtIndex(0, $dx11ShaderPresetUniformAttributes); 15 | 16 | // Skip attributes not exposed in the UI: 17 | if( `attributeQuery -n $gAEAttrPresetCurrentTarget -h $dx11ShaderPresetCurrentAttr` == 1) 18 | continue; 19 | 20 | // Skip unsupported types 21 | if (`attributeExists ($dx11ShaderPresetCurrentAttr + "_Type") $gAEAttrPresetCurrentTarget`) 22 | { 23 | string $dx11ShaderPresetAttrType = `getAttr ($gAEAttrPresetCurrentTarget + "." + $dx11ShaderPresetCurrentAttr + "_Type")`; 24 | switch ( $dx11ShaderPresetAttrType ) 25 | { 26 | case "bool": 27 | case "int": 28 | case "enum": 29 | case "float": 30 | case "float2x1": 31 | case "float1x2": 32 | case "float3x1": 33 | case "float1x3": 34 | case "float4x1": 35 | case "float1x4": 36 | case "color3x1": 37 | case "color1x3": 38 | case "color4x1": 39 | case "color1x4": 40 | break; // Supported 41 | default: 42 | continue; // Unsupported 43 | } 44 | } 45 | 46 | string $dx11ShaderPresetChildren[] = `attributeQuery -node $gAEAttrPresetCurrentTarget -listChildren $dx11ShaderPresetCurrentAttr`; 47 | if (size($dx11ShaderPresetChildren)) { 48 | // Add the children to the list of attributes to process: 49 | $dx11ShaderPresetUniformAttributes = stringArrayCatenate($dx11ShaderPresetChildren, $dx11ShaderPresetUniformAttributes); 50 | } else { 51 | // This one is a leaf attribute, request a preset blend: 52 | float $dx11ShaderPresetDefaultVal[] = `attributeQuery -node $gAEAttrPresetCurrentTarget -listDefault $dx11ShaderPresetCurrentAttr`; 53 | blendAttr $dx11ShaderPresetCurrentAttr $dx11ShaderPresetDefaultVal[0]; 54 | } 55 | } 56 | } 57 | endAttrPreset(); 58 | -------------------------------------------------------------------------------- /dx11Shader_initUI.mel: -------------------------------------------------------------------------------- 1 | // Code adapted from the CgFX plugin by NVidia // 2 | // This script is run automatically when the dx11Shader plug-in is loaded. 3 | 4 | { 5 | // Set default definitions for tool buttons in dx11Shader attribute editor. 6 | // [0]: for each of the 2 tool buttons, the assigned tool name (tab separated) 7 | // [1..N]: any number of tool definitions consisting of tab-separated 8 | // tool name, icon, description, and MEL command string 9 | string $s = "AEdx11Shader_toolSymbolButtons"; 10 | if ( !`about -batch` && 11 | !`optionVar -exists $s` ) 12 | { 13 | string $reloadTool = getPluginResource( "dx11Shader", "kReloadTool"); 14 | string $reloadIcon = "refresh.png"; 15 | string $reloadAnnotation = getPluginResource( "dx11Shader", "kReloadAnnotation"); 16 | string $reloadCommand = "dx11Shader -r ;"; 17 | 18 | string $editTool = getPluginResource( "dx11Shader", "kEditTool"); 19 | string $editIcon = "fileTextureEdit.png"; 20 | string $editAnnotation; 21 | string $editCommand; 22 | 23 | if ( `about -nt` ) { 24 | $editAnnotation = getPluginResource( "dx11Shader", "kEditAnnotationWIN"); 25 | $editCommand = "system \"load \";"; 26 | } 27 | else if ( `about -macOS` ) { 28 | $editAnnotation = getPluginResource( "dx11Shader", "kEditAnnotationMAC"); 29 | $editCommand = "open -a TextEdit ;"; 30 | } 31 | else { 32 | $editAnnotation = getPluginResource( "dx11Shader", "kEditAnnotationLNX"); 33 | $editCommand = getPluginResource( "dx11Shader", "kEditCommandLNX"); 34 | } 35 | 36 | string $tools = $reloadTool + "\t" + $editTool; 37 | string $reloadArgs = $reloadTool + "\t" + $reloadIcon + "\t" + $reloadAnnotation + "\t" + $reloadCommand; 38 | string $editArgs = $editTool + "\t" + $editIcon + "\t" + $editAnnotation + "\t" + $editCommand; 39 | 40 | optionVar -sva $s ($tools) 41 | -sva $s ($reloadArgs) 42 | -sva $s ($editArgs) 43 | ; 44 | } 45 | } 46 | --------------------------------------------------------------------------------