bool Material::parsePass(Technique* technique, Properties* passProperties) { auto pass = Pass::create(technique); technique->addPass(pass); // Pass can have 3 different namespaces: // - one or more "sampler" // - one "renderState" // - one "shader" auto space = passProperties->getNextNamespace(); while (space) { const char* name = space->getNamespace(); if (strcmp(name, "shader") == 0) parseShader(pass, space); else if (strcmp(name, "renderState") == 0) parseRenderState(pass, space); else { CCASSERT(false, "Invalid namespace"); return false; } space = passProperties->getNextNamespace(); } return true; }
/////////////////////////////////////////////////////////////////////// // Class : CRendererContext // Method : getShader // Description : Create an instance of a shader // Return Value : // Comments : CShader *CRenderer::getShader(const char *name,TSearchpath *path) { CShader *cShader; CFileResource *file; assert(name != NULL); if (strcmp(name,RI_DEFAULTSURFACE) == 0) name = RI_MATTE; assert(globalFiles != NULL); // Check if we already loaded this shader before ... cShader = NULL; if (globalFiles->find(name,file)) { cShader = (CShader *) file; } else { char shaderLocation[OS_MAX_PATH_LENGTH]; if (CRenderer::locateFileEx(shaderLocation,name,"sdr",path) == TRUE) { cShader = parseShader(name,shaderLocation); if (cShader != NULL) { globalFiles->insert(cShader->name,cShader); } } } return cShader; }
void Shader::init() { _loaded = true; _programObj = glCreateProgram(); assert(_vert); GLhandleARB vertexShader = parseShader(_vert, GL_VERTEX_SHADER); assert(vertexShader); glAttachShader(_programObj, vertexShader); glDeleteShader(vertexShader); assert(_frag); GLhandleARB fragmentShader = parseShader(_frag, GL_FRAGMENT_SHADER); assert(fragmentShader); glAttachShader(_programObj, fragmentShader); glDeleteShader(fragmentShader); glLinkProgram(_programObj); assert(_programObj); glUseProgram(_programObj); glUniform1i(glGetUniformLocation(_programObj, "texture0"), 0); glUniform1i(glGetUniformLocation(_programObj, "texture1"), 1); glUniform1i(glGetUniformLocation(_programObj, "texture2"), 2); glUniform1i(glGetUniformLocation(_programObj, "texture3"), 3); glUniform1f(glGetUniformLocation(_programObj, "time"), 0.0); glUniform1f(glGetUniformLocation(_programObj, "wobble"), 0.0); glUniform1f(glGetUniformLocation(_programObj, "flare"), 0.0); glUniform1f(glGetUniformLocation(_programObj, "bloomScale"), 0.0); glUniform1f(glGetUniformLocation(_programObj, "bloomShift"), 0.0); glUniform1f(glGetUniformLocation(_programObj, "repeat"), 0.0); glUseProgram(NULL); // assert(glGetError() == GL_NO_ERROR); }
// ParticleAttribute, ParticleBehavior, ParticleShader name bool PSClass::parseClass(istringstream &token) { bool result=true; // class type if (!nextToken.compare("Attribute")) classType=ATTRIBUTE; else if (!nextToken.compare("Behavior")) classType=BEHAVIOR; else if (!nextToken.compare("Shader")) classType=SHADER; else { cout << "Translation stopped because no such class type: " << nextToken <<endl; result=false; } baseClassName="Particle"+nextToken; // name token >> className; // open { token >> nextToken; if (nextToken.compare("{")) result=false; // can be parameters or functions token >> nextToken; // parse rest while(true) { if (!nextToken.compare("Parameters")) { result = result && parseParameters(token); if (!result) break; } else if (!nextToken.compare("attachAttributes")) { result = result && parseAttachAttributes(token); if (!result) break; } else if (!nextToken.compare("Behavior")) { result = result && parseBehavior(token); if (!result) break; } else if (!nextToken.compare("Shader")) { result = result && parseShader(token); if (!result) break; } else if (!nextToken.compare("}")) break; else { cout << "Translation stopped because cannot parse token: " << nextToken<< ". Expecting end of class." <<endl; break; } } // close } if (nextToken.compare("}")) result=false; return result; }
MStatus CXRayObjectExport::ExportPart(CEditableObject* O, MDagPath& mdagPath, MObject& mComponent) { MStatus stat = MS::kSuccess; MSpace::Space space = MSpace::kWorld; MFnMesh fnMesh( mdagPath, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MFnMesh initialization.\n"); return MS::kFailure; } MString mdagPathNodeName = fnMesh.name(); MFnDagNode dagNode1(mdagPath); u32 pc = dagNode1.parentCount(); for(u32 ip=0;ip<pc;++ip) { MObject object_parent = dagNode1.parent(ip, &stat); if(object_parent.hasFn(MFn::kTransform)) { MFnTransform parent_transform(object_parent,&stat); if ( MS::kSuccess == stat) { mdagPathNodeName = parent_transform.name(); break; } } } MItMeshPolygon meshPoly( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshPolygon initialization.\n"); return MS::kFailure; } MItMeshVertex vtxIter( mdagPath, mComponent, &stat ); if ( MS::kSuccess != stat) { fprintf(stderr,"Failure in MItMeshVertex initialization.\n"); return MS::kFailure; } // If the shape is instanced then we need to determine which // instance this path refers to. // int instanceNum = 0; if (mdagPath.isInstanced()) instanceNum = mdagPath.instanceNumber(); // Get a list of all shaders attached to this mesh MObjectArray rgShaders; MIntArray texMap; MStatus status; status = fnMesh.getConnectedShaders (instanceNum, rgShaders, texMap); if (status == MStatus::kFailure) { Log("! Unable to load shaders for mesh"); return (MStatus::kFailure); } XRShaderDataVec xr_data; { for ( int i=0; i<(int)rgShaders.length(); i++ ) { MObject shader = rgShaders[i]; xr_data.push_back(SXRShaderData()); SXRShaderData& D = xr_data.back(); status = parseShader(shader, D); if (status == MStatus::kFailure) { status.perror ("Unable to retrieve filename of texture"); continue; } } } CEditableMesh* MESH = new CEditableMesh(O); MESH->SetName(mdagPathNodeName.asChar()); O->AppendMesh(MESH); int objectIdx, length; // Find i such that objectGroupsTablePtr[i] corresponds to the // object node pointed to by mdagPath length = objectNodeNamesArray.length(); { for( int i=0; i<length; i++ ) { if( objectNodeNamesArray[i] == mdagPathNodeName ) { objectIdx = i; break; } } } // Reserve uv table { VMapVec& _vmaps = MESH->m_VMaps; _vmaps.resize (1); st_VMap*& VM = _vmaps.back(); VM = new st_VMap("Texture",vmtUV,false); } // write faces { using FaceVec = xr_vector<st_Face>; using FaceIt = FaceVec::iterator; VMapVec& _vmaps = MESH->m_VMaps; SurfFaces& _surf_faces = MESH->m_SurfFaces; VMRefsVec& _vmrefs = MESH->m_VMRefs; // temp variables FvectorVec _points; FaceVec _faces; U32Vec _sgs; int f_cnt = fnMesh.numPolygons(); _sgs.reserve (f_cnt); _faces.reserve (f_cnt); _vmrefs.reserve (f_cnt*3); // int lastSmoothingGroup = INITIALIZE_SMOOTHING; MPointArray rgpt; MIntArray rgint; PtLookupMap ptMap; CSurface* surf = 0; for ( ; !meshPoly.isDone(); meshPoly.next()){ // Write out the smoothing group that this polygon belongs to // We only write out the smoothing group if it is different // from the last polygon. // int compIdx = meshPoly.index(); int smoothingGroup = polySmoothingGroups[ compIdx ]; // for each polygon, first setup the reverse mapping // between object-relative vertex indices and face-relative // vertex indices ptMap.clear(); for (int i=0; i<(int)meshPoly.polygonVertexCount(); i++) ptMap.insert (PtLookupMap::value_type(meshPoly.vertexIndex(i), i) ); // verify polygon zero area if (meshPoly.zeroArea()){ status = MS::kFailure; Log("! polygon have zero area:",meshPoly.index()); return status; } // verify polygon zero UV area /* if (meshPoly.zeroUVArea()){ status = MS::kFailure; Log("! polygon have zero UV area:",meshPoly.index()); return status; } */ // verify polygon has UV information if (!meshPoly.hasUVs (&status)) { status = MS::kFailure; Log("! polygon is missing UV information:",meshPoly.index()); return status; } int cTri; // now iterate through each triangle on this polygon and create a triangle object in our list status = meshPoly.numTriangles (cTri); if (!status) { Log("! can't getting triangle count"); return status; } for (int i=0; i < cTri; i++) { // for each triangle, first get the triangle data rgpt.clear();//triangle vertices rgint.clear();//triangle vertex indices // triangles that come from object are retrieved in world space status = meshPoly.getTriangle (i, rgpt, rgint, MSpace::kWorld); if (!status) { Log("! can't getting triangle for mesh poly"); return status; } if ((rgpt.length() != 3) || (rgint.length() != 3)) { Msg("! 3 points not returned for triangle"); return MS::kFailure; } // Write out vertex/uv index information // R_ASSERT2(fnMesh.numUVs()>0,"Can't find uvmaps."); _faces.push_back(st_Face()); _sgs.push_back(smoothingGroup); //set_smooth set_smoth_flags( _sgs.back(), rgint ); st_Face& f_it = _faces.back(); for ( int vtx=0; vtx<3; vtx++ ) { // get face-relative vertex PtLookupMap::iterator mapIt; int vtLocal, vtUV; int vt = rgint[vtx]; mapIt = ptMap.find(vt); Fvector2 uv; if (mapIt == ptMap.end()){ Msg("! Can't find local index."); return MS::kFailure; } vtLocal = (*mapIt).second; status = meshPoly.getUVIndex (vtLocal, vtUV, uv.x, uv.y); if (!status) { Msg("! error getting UV Index for local vertex '%d' and object vertex '%d'",vtLocal,vt); return status; } // flip v-part uv.y=1.f-uv.y; f_it.pv[2-vtx].pindex = AppendVertex(_points,rgpt[vtx]); f_it.pv[2-vtx].vmref = _vmrefs.size(); _vmrefs.push_back (st_VMapPtLst()); st_VMapPtLst& vm_lst = _vmrefs.back(); vm_lst.count = 1; vm_lst.pts = xr_alloc<st_VMapPt>(vm_lst.count); vm_lst.pts[0].vmap_index= 0; vm_lst.pts[0].index = AppendUV(_vmaps.back(),uv); } // out face material int iTexture = texMap[meshPoly.index()]; if (iTexture<0) xrDebug::Fatal(DEBUG_INFO,"Can't find material for polygon: %d",meshPoly.index()); SXRShaderData& D= xr_data[iTexture]; int compIdx = meshPoly.index(); surf = MESH->Parent()->CreateSurface(getMaterialName(mdagPath, compIdx, objectIdx),D); if (!surf) return MStatus::kFailure; _surf_faces[surf].push_back(_faces.size()-1); } } { // copy from temp MESH->m_VertCount = _points.size(); MESH->m_FaceCount = _faces.size(); MESH->m_Vertices = xr_alloc<Fvector>(MESH->m_VertCount); Memory.mem_copy (MESH->m_Vertices,&*_points.begin(),MESH->m_VertCount*sizeof(Fvector)); MESH->m_Faces = xr_alloc<st_Face>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_Faces,&*_faces.begin(),MESH->m_FaceCount*sizeof(st_Face)); MESH->m_SmoothGroups = xr_alloc<u32>(MESH->m_FaceCount); Memory.mem_copy (MESH->m_SmoothGroups,&*_sgs.begin(),MESH->m_FaceCount*sizeof(u32)); MESH->RecomputeBBox (); } if ((MESH->GetVertexCount()<4)||(MESH->GetFaceCount()<2)) { Log ("! Invalid mesh: '%s'. Faces<2 or Verts<4",*MESH->Name()); return MS::kFailure; } } return stat; }