Browse Source

Attribute arrays are now kept track of in the ShaderPass, allowed for custom named attribute arrays in Mesh, restored skeletal animation support in SceneMesh

Ivan Safrin 10 years ago
parent
commit
847063c5d7

BIN
assets/default/default.pak


+ 6 - 1
include/polycode/core/PolyMaterial.h

@@ -33,18 +33,23 @@ namespace Polycode {
 	class ShaderBinding;
 	class ShaderRenderTarget;
     class Mesh;
+    class VertexDataArray;
     
     class _PolyExport ShaderPass {
         public:
             ShaderPass();
             ShaderPass(Shader *shader);
         
-            void setExpectedAttributes(Mesh *mesh);
+            void setAttributeArraysFromMesh(Mesh *mesh);
+            void setExpectedAttributes();
+            static String arrayToAttributeName(VertexDataArray *array);
         
             Shader *shader;
             bool wireframe;
             unsigned short blendingMode;
             ShaderBinding* shaderBinding;
+        
+            std::vector<VertexDataArray*> attributeArrays;
     };
 
 	class _PolyExport Material : public Resource {

+ 2 - 0
include/polycode/core/PolyRenderDataArray.h

@@ -22,6 +22,7 @@
 
 #pragma once
 #include "polycode/core/PolyGlobals.h"
+#include "polycode/core/PolyString.h"
 #include <vector>
 
 namespace Polycode {
@@ -34,6 +35,7 @@ namespace Polycode {
         virtual void *getArrayData();
         virtual unsigned int getDataSize();
         
+        String customArrayName;
         bool hasVBO;
         void *platformData;
         

+ 1 - 1
include/polycode/core/PolySceneMesh.h

@@ -132,7 +132,7 @@ namespace Polycode {
 			*/
 			Skeleton *getSkeleton();
 		
-			void renderMeshLocally();
+			void applySkeletonLocally();
 			
             /**
              * Sets the line width for line-based meshes.

+ 57 - 23
src/core/PolyMaterial.cpp

@@ -49,38 +49,72 @@ ShaderPass::ShaderPass(Shader *shader) :
     
 }
 
-void ShaderPass::setExpectedAttributes(Mesh *mesh) {
+ String ShaderPass::arrayToAttributeName(VertexDataArray *array) {
+    switch(array->type) {
+        case RenderDataArray::VERTEX_DATA_ARRAY:
+            return "position";
+        break;
+        case RenderDataArray::NORMAL_DATA_ARRAY:
+            return "normal";
+        break;
+        case RenderDataArray::TEXCOORD_DATA_ARRAY:
+            return "texCoord";
+        break;
+        case RenderDataArray::COLOR_DATA_ARRAY:
+            return "color";
+        break;
+        case RenderDataArray::TANGENT_DATA_ARRAY:
+            return "tangent";
+        break;
+        case RenderDataArray::TEXCOORD2_DATA_ARRAY:
+            return "texCoord2";
+        break;
+        case RenderDataArray::BONE_WEIGHT_DATA_ARRAY:
+            return "boneWeights";
+        break;
+        case RenderDataArray::BONE_INDEX_DATA_ARRAY:
+            return "boneIndices";
+        break;
+        default:
+            return array->customArrayName;
+        break;
+    }
+}
+
+void ShaderPass::setAttributeArraysFromMesh(Mesh *mesh) {
+    attributeArrays.clear();
+    attributeArrays.push_back(&mesh->vertexPositionArray);
+    attributeArrays.push_back(&mesh->vertexNormalArray);
+    attributeArrays.push_back(&mesh->vertexTexCoordArray);
+    attributeArrays.push_back(&mesh->vertexColorArray);
+    attributeArrays.push_back(&mesh->vertexBoneIndexArray);
+    attributeArrays.push_back(&mesh->vertexBoneWeightArray);
+    attributeArrays.push_back(&mesh->vertexTangentArray);
+    attributeArrays.push_back(&mesh->vertexTexCoord2Array);
+}
+
+void ShaderPass::setExpectedAttributes() {
     if(!shader || !shaderBinding) {
         return;
     }
     shaderBinding->attributes.clear();
-
+    
     for(int i=0; i < shader->expectedAttributes.size(); i++) {
         VertexDataArray *targetArray = NULL;
         
-        if(shader->expectedAttributes[i].name == "position") {
-            targetArray = &mesh->vertexPositionArray;
-        } else if(shader->expectedAttributes[i].name == "texCoord"){
-            targetArray = &mesh->vertexTexCoordArray;
-        } else if(shader->expectedAttributes[i].name == "normal") {
-            targetArray = &mesh->vertexNormalArray;
-        } else if(shader->expectedAttributes[i].name == "color") {
-            targetArray = &mesh->vertexColorArray;
-        } else if(shader->expectedAttributes[i].name == "tangent") {
-            targetArray = &mesh->vertexTangentArray;
-        } else if(shader->expectedAttributes[i].name == "texCoord2") {
-            targetArray = &mesh->vertexTexCoord2Array;
-        } else if(shader->expectedAttributes[i].name == "boneWeights") {
-            targetArray = &mesh->vertexBoneWeightArray;
-        } else if(shader->expectedAttributes[i].name == "boneIndices") {
-            targetArray = &mesh->vertexBoneIndexArray;
+        for(int j=0; j < attributeArrays.size(); j++)  {
+            if(shader->expectedAttributes[i].name == arrayToAttributeName(attributeArrays[j])) {
+                targetArray = attributeArrays[j];
+            }
         }
         
-        AttributeBinding *attributeBinding = shaderBinding->getAttributeBindingByName(shader->expectedAttributes[i].name);
-        if(attributeBinding) {
-            attributeBinding->vertexData = targetArray;
-        } else {
-            shaderBinding->addAttributeBinding(shader->expectedAttributes[i].name, targetArray);
+        if(targetArray) {
+            AttributeBinding *attributeBinding = shaderBinding->getAttributeBindingByName(shader->expectedAttributes[i].name);
+            if(attributeBinding) {
+                attributeBinding->vertexData = targetArray;
+            } else {
+                shaderBinding->addAttributeBinding(shader->expectedAttributes[i].name, targetArray);
+            }
         }
     }
 }

+ 1 - 1
src/core/PolyRenderer.cpp

@@ -246,7 +246,7 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                 }
                 
                 if(rebindAttributes || localShaderBinding->resetAttributes ) {
-                    buffer->drawCalls[i].shaderPasses[s].setExpectedAttributes(buffer->drawCalls[i].mesh);
+                    buffer->drawCalls[i].shaderPasses[s].setExpectedAttributes();
                     localShaderBinding->resetAttributes = false;
                 }
 

+ 55 - 73
src/core/PolySceneMesh.cpp

@@ -55,7 +55,7 @@ SceneMesh::SceneMesh(const String& fileName) : Entity(), material(NULL), skeleto
     backfaceCulled = true;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
-    setMaterialByName("Unlit");
+    setMaterialByName("UnlitUntextured");
 }
 
 SceneMesh::SceneMesh(Mesh *mesh) : Entity(), material(NULL), skeleton(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
@@ -71,7 +71,7 @@ SceneMesh::SceneMesh(Mesh *mesh) : Entity(), material(NULL), skeleton(NULL), ske
     backfaceCulled = true;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
-    setMaterialByName("Unlit");
+    setMaterialByName("UnlitUntextured");
 }
 
 SceneMesh::SceneMesh(int meshType) : material(NULL), skeleton(NULL), skeletalVertexPositions(3, RenderDataArray::VERTEX_DATA_ARRAY), skeletalVertexNormals(3, RenderDataArray::NORMAL_DATA_ARRAY) {
@@ -86,7 +86,7 @@ SceneMesh::SceneMesh(int meshType) : material(NULL), skeleton(NULL), skeletalVer
     backfaceCulled = true;
 	alphaTest = false;
     sendBoneMatricesToMaterial = false;
-    setMaterialByName("Unlit");
+    setMaterialByName("UnlitUntextured");
 }
 
 void SceneMesh::setMesh(Mesh *mesh) {
@@ -103,6 +103,11 @@ void SceneMesh::setMesh(Mesh *mesh) {
 
 void SceneMesh::rebuildAttributes() {
     for(int i=0; i < shaderPasses.size(); i++) {
+        shaderPasses[i].setAttributeArraysFromMesh(mesh);
+        if(skeleton) {
+            shaderPasses[i].attributeArrays.push_back(&skeletalVertexPositions);
+            shaderPasses[i].attributeArrays.push_back(&skeletalVertexNormals);
+        }
         shaderPasses[i].shaderBinding->resetAttributes = true;
     }
 }
@@ -206,6 +211,11 @@ void SceneMesh::setMaterial(Material *material) {
         shaderPass.shaderBinding->targetShader = shaderPass.shader;
         shaderPass.shaderBinding->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
         shaderPass.shaderBinding->resetAttributes = true;
+        shaderPass.setAttributeArraysFromMesh(mesh);
+        if(skeleton) {
+            shaderPass.attributeArrays.push_back(&skeletalVertexPositions);
+            shaderPass.attributeArrays.push_back(&skeletalVertexNormals);
+        }
         shaderPasses.push_back(shaderPass);
     }
     
@@ -247,6 +257,7 @@ Skeleton *SceneMesh::loadSkeleton(const String& fileName) {
 
 void SceneMesh::setSkeleton(Skeleton *skeleton) {
 	this->skeleton = skeleton;
+    rebuildAttributes();
 }
 
 void SceneMesh::setLineWidth(Number newWidth) {
@@ -261,76 +272,6 @@ Skeleton *SceneMesh::getSkeleton() {
 	return skeleton;
 }
 
-void SceneMesh::renderMeshLocally() {
-    /*
-	Renderer *renderer = CoreServices::getInstance()->getRenderer();
-
-	
-	if(skeleton) {
-        
-        skeletalVertexPositions.data.clear();
-        skeletalVertexNormals.data.clear();
-        
-		for(int i=0; i < mesh->vertexPositionArray.data.size()/3; i++) {
-            
-            Vector3 norm;
-            Vector3 tPos;
-            
-            for(int b=0; b < 4; b++) {
-            
-                PolyRendererVertexType boneWeight = mesh->vertexBoneWeightArray.data[(i*4)+b];
-                
-                if(boneWeight > 0.0) {
-                    
-                    Bone *bone = skeleton->getBone(mesh->vertexBoneIndexArray.data[(i*4)+b]);
-                    if(bone) {
-                        Vector3 restVert(mesh->vertexPositionArray.data[i*3], mesh->vertexPositionArray.data[(i*3)+1], mesh->vertexPositionArray.data[(i*3)+2]);
-                        
-                        tPos += bone->finalMatrix * restVert * (boneWeight);
-                            
-                        Vector3 nvec(mesh->vertexNormalArray.data[i*3], mesh->vertexNormalArray.data[(i*3)+1], mesh->vertexNormalArray.data[(i*3)+2]);
-                        
-                        nvec = bone->finalMatrix.rotateVector(nvec);
-                        
-                        norm += nvec * (boneWeight);
-                    }
-                }
-            }
-
-            skeletalVertexPositions.data.push_back(tPos.x);
-            skeletalVertexPositions.data.push_back(tPos.y);
-            skeletalVertexPositions.data.push_back(tPos.z);
-        
-            norm.Normalize();
-            
-            skeletalVertexNormals.data.push_back(norm.x);
-            skeletalVertexNormals.data.push_back(norm.y);
-            skeletalVertexNormals.data.push_back(norm.z);
-        }
-        
-        renderer->pushRenderDataArray(&skeletalVertexPositions);
-        renderer->pushRenderDataArray(&skeletalVertexNormals);
-        
-    } else {
-        renderer->pushRenderDataArray(&mesh->vertexPositionArray);
-        renderer->pushRenderDataArray(&mesh->vertexNormalArray);
-    }
-    
-    renderer->pushRenderDataArray(&mesh->vertexTangentArray);
-    renderer->pushRenderDataArray(&mesh->vertexTexCoordArray);
-    
-	if(mesh->useVertexColors) {
-		renderer->pushRenderDataArray(&mesh->vertexColorArray);
-	}
-    
-    if(mesh->indexedMesh) {
-        renderer->drawArrays(mesh->getMeshType(), &mesh->indexArray);
-    } else {
-        renderer->drawArrays(mesh->getMeshType(), NULL);
-    }
-     */
-}
-
 bool SceneMesh::customHitDetection(const Ray &ray) {
 	if(!useGeometryHitDetection)
 		return true;
@@ -371,6 +312,43 @@ void SceneMesh::removeShaderPass(int shaderIndex) {
     }
 }
 
+void SceneMesh::applySkeletonLocally() {
+    skeletalVertexPositions.data.clear();
+    skeletalVertexNormals.data.clear();
+    
+    for(int i=0; i < mesh->vertexPositionArray.data.size()/3; i++) {
+        
+        Vector3 norm;
+        Vector3 tPos;
+        
+        for(int b=0; b < 4; b++) {
+            
+            PolyRendererVertexType boneWeight = mesh->vertexBoneWeightArray.data[(i*4)+b];
+            if(boneWeight > 0.0) {
+                Bone *bone = skeleton->getBone(mesh->vertexBoneIndexArray.data[(i*4)+b]);
+                if(bone) {
+                    Vector3 restVert(mesh->vertexPositionArray.data[i*3], mesh->vertexPositionArray.data[(i*3)+1], mesh->vertexPositionArray.data[(i*3)+2]);
+                    tPos += bone->finalMatrix * restVert * (boneWeight);
+                    Vector3 nvec(mesh->vertexNormalArray.data[i*3], mesh->vertexNormalArray.data[(i*3)+1], mesh->vertexNormalArray.data[(i*3)+2]);
+                    
+                    nvec = bone->finalMatrix.rotateVector(nvec);
+                    norm += nvec * (boneWeight);
+                }
+            }
+        }
+        
+        skeletalVertexPositions.data.push_back(tPos.x);
+        skeletalVertexPositions.data.push_back(tPos.y);
+        skeletalVertexPositions.data.push_back(tPos.z);
+        
+        norm.Normalize();
+        
+        skeletalVertexNormals.data.push_back(norm.x);
+        skeletalVertexNormals.data.push_back(norm.y);
+        skeletalVertexNormals.data.push_back(norm.z);
+    }
+}
+
 void SceneMesh::Render(GPUDrawBuffer *buffer) {
     
     drawCall.options.alphaTest = alphaTest;
@@ -383,6 +361,10 @@ void SceneMesh::Render(GPUDrawBuffer *buffer) {
     drawCall.material = material;
     drawCall.shaderPasses = shaderPasses;
     
+    if(skeleton) {
+        applySkeletonLocally();
+    }
+    
     buffer->drawCalls.push_back(drawCall);
     
     /*

+ 2 - 1
src/ide/PolycodeEntityEditor.cpp

@@ -1796,7 +1796,8 @@ void EntityEditorMainView::setOverlayWireframeRecursive(Entity *targetEntity, bo
                 wireframePass.shaderBinding = new ShaderBinding();
                 wireframePass.shaderBinding->targetShader = wireframePass.shader;
                 wireframePass.blendingMode = Renderer::BLEND_MODE_NORMAL;
-                wireframePass.setExpectedAttributes(sceneMesh->getMesh());
+                wireframePass.setAttributeArraysFromMesh(sceneMesh->getMesh());
+                wireframePass.shaderBinding->resetAttributes = true;
                 wireframePass.shaderBinding->addParam(ProgramParam::PARAM_COLOR, "wireframeColor")->setColor(Color(0.5, 0.6, 1.0, 0.75));
                 
                 sceneMesh->addShaderPass(wireframePass);

+ 1 - 0
src/modules/ui/PolyUIElement.cpp

@@ -327,6 +327,7 @@ void UIRect::setMaterial(Material *material) {
     shaderPasses.push_back(pass);
     
     shaderPasses[0].shaderBinding->addParamPointer(ProgramParam::PARAM_COLOR, "entityColor", &color);
+    shaderPasses[0].setAttributeArraysFromMesh(rectMesh);
     shaderPasses[0].shaderBinding->resetAttributes = true;
 }