// Mesh bin export bool exportMeshBin(const char * filename, MMesh * mesh) { int version = 2; char rep[256]; bool state; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // get file directory getRepertory(rep, filename); // header M_fwrite(M_MESH_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // Animation { // anim refs MArmatureAnimRef * armatureAnimRef = mesh->getArmatureAnimRef(); MTexturesAnimRef * texturesAnimRef = mesh->getTexturesAnimRef(); MMaterialsAnimRef * materialsAnimRef = mesh->getMaterialsAnimRef(); // armature anim ref writeDataRef(file, armatureAnimRef, rep); // textures anim ref writeDataRef(file, texturesAnimRef, rep); // materials anim ref writeDataRef(file, materialsAnimRef, rep); // anims ranges unsigned int animsRangesNumber = mesh->getAnimsRangesNumber(); MAnimRange * animsRanges = mesh->getAnimsRanges(); M_fwrite(&animsRangesNumber, sizeof(int), 1, file); if(animsRangesNumber > 0) M_fwrite(animsRanges, sizeof(MAnimRange), animsRangesNumber, file); } // Textures { unsigned int t, texturesNumber = mesh->getTexturesNumber(); M_fwrite(&texturesNumber, sizeof(int), 1, file); for(t=0; t<texturesNumber; t++) { MTexture * texture = mesh->getTexture(t); MTextureRef * textureRef = texture->getTextureRef(); M_TEX_GEN_MODES genMode = texture->getGenMode(); M_WRAP_MODES UWrapMode = texture->getUWrapMode(); M_WRAP_MODES VWrapMode = texture->getVWrapMode(); MVector2 texTranslate = texture->getTexTranslate(); MVector2 texScale = texture->getTexScale(); float texRotate = texture->getTexRotate(); // texture ref writeDataRef(file, textureRef, rep); if(textureRef) { bool mipmap = textureRef->isMipmapEnabled(); M_fwrite(&mipmap, sizeof(bool), 1, file); } // data M_fwrite(&genMode, sizeof(M_TEX_GEN_MODES), 1, file); M_fwrite(&UWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&VWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&texTranslate, sizeof(MVector2), 1, file); M_fwrite(&texScale, sizeof(MVector2), 1, file); M_fwrite(&texRotate, sizeof(float), 1, file); } } // Materials { unsigned int m, materialsNumber = mesh->getMaterialsNumber(); M_fwrite(&materialsNumber, sizeof(int), 1, file); for(m=0; m<materialsNumber; m++) { MMaterial * material = mesh->getMaterial(m); int type = material->getType(); float opacity = material->getOpacity(); float shininess = material->getShininess(); float customValue = material->getCustomValue(); M_BLENDING_MODES blendMode = material->getBlendMode(); MVector3 emit = material->getEmit(); MVector3 diffuse = material->getDiffuse(); MVector3 specular = material->getSpecular(); MVector3 customColor = material->getCustomColor(); MFXRef * FXRef = material->getFXRef(); MFXRef * ZFXRef = material->getZFXRef(); // FX ref state = FXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(FXRef) { MShaderRef * vertShadRef = FXRef->getVertexShaderRef(); MShaderRef * pixShadRef = FXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // Z FX ref state = ZFXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(ZFXRef) { MShaderRef * vertShadRef = ZFXRef->getVertexShaderRef(); MShaderRef * pixShadRef = ZFXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // data M_fwrite(&type, sizeof(int), 1, file); M_fwrite(&opacity, sizeof(float), 1, file); M_fwrite(&shininess, sizeof(float), 1, file); M_fwrite(&customValue, sizeof(float), 1, file); M_fwrite(&blendMode, sizeof(M_BLENDING_MODES), 1, file); M_fwrite(&emit, sizeof(MVector3), 1, file); M_fwrite(&diffuse, sizeof(MVector3), 1, file); M_fwrite(&specular, sizeof(MVector3), 1, file); M_fwrite(&customColor, sizeof(MVector3), 1, file); // textures pass unsigned int t, texturesPassNumber = material->getTexturesPassNumber(); M_fwrite(&texturesPassNumber, sizeof(int), 1, file); for(t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); unsigned int mapChannel = texturePass->getMapChannel(); M_TEX_COMBINE_MODES combineMode = texturePass->getCombineMode(); // texture id int textureId = getTextureId(mesh, texture); M_fwrite(&textureId, sizeof(int), 1, file); // data M_fwrite(&mapChannel, sizeof(int), 1, file); M_fwrite(&combineMode, sizeof(M_TEX_COMBINE_MODES), 1, file); } } } // Bones { MArmature * armature = mesh->getArmature(); state = armature != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(armature) { unsigned int b, bonesNumber = armature->getBonesNumber(); M_fwrite(&bonesNumber, sizeof(int), 1, file); for(b=0; b<bonesNumber; b++) { MOBone * bone = armature->getBone(b); MObject3d * parent = bone->getParent(); MVector3 position = bone->getPosition(); MVector3 scale = bone->getScale(); MQuaternion rotation = bone->getRotation(); // name writeString(file, bone->getName()); // parent id int parentId = -1; if(parent) { unsigned int id; if(armature->getBoneId(parent->getName(), &id)) parentId = (int)id; } M_fwrite(&parentId, sizeof(int), 1, file); // position / rotation / scale M_fwrite(&position, sizeof(MVector3), 1, file); M_fwrite(&rotation, sizeof(MQuaternion), 1, file); M_fwrite(&scale, sizeof(MVector3), 1, file); } } } // BoundingBox { MBox3d * box = mesh->getBoundingBox(); M_fwrite(box, sizeof(MBox3d), 1, file); } // SubMeshs { unsigned int s, subMeshsNumber = mesh->getSubMeshsNumber(); MSubMesh * subMeshs = mesh->getSubMeshs(); M_fwrite(&subMeshsNumber, sizeof(int), 1, file); for(s=0; s<subMeshsNumber; s++) { MSubMesh * subMesh = &(subMeshs[s]); unsigned int indicesSize = subMesh->getIndicesSize(); unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); unsigned int tangentsSize = subMesh->getTangentsSize(); unsigned int texCoordsSize = subMesh->getTexCoordsSize(); unsigned int colorsSize = subMesh->getColorsSize(); M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MColor * colors = subMesh->getColors(); MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector3 * tangents = subMesh->getTangents(); MVector2 * texCoords = subMesh->getTexCoords(); MBox3d * box = subMesh->getBoundingBox(); MSkinData * skin = subMesh->getSkinData(); map<unsigned int, unsigned int> * mapChannelOffsets = subMesh->getMapChannelOffsets(); // BoundingBox M_fwrite(box, sizeof(MBox3d), 1, file); // indices M_fwrite(&indicesSize, sizeof(int), 1, file); if(indicesSize > 0) { // indice type M_fwrite(&indicesType, sizeof(M_TYPES), 1, file); switch(indicesType) { case M_USHORT: M_fwrite(indices, sizeof(short), indicesSize, file); break; case M_UINT: M_fwrite(indices, sizeof(int), indicesSize, file); break; } } // vertices M_fwrite(&verticesSize, sizeof(int), 1, file); if(verticesSize > 0) M_fwrite(vertices, sizeof(MVector3), verticesSize, file); // normals M_fwrite(&normalsSize, sizeof(int), 1, file); if(normalsSize > 0) M_fwrite(normals, sizeof(MVector3), normalsSize, file); // tangents M_fwrite(&tangentsSize, sizeof(int), 1, file); if(tangentsSize > 0) M_fwrite(tangents, sizeof(MVector3), tangentsSize, file); // texCoords M_fwrite(&texCoordsSize, sizeof(int), 1, file); if(texCoordsSize > 0) M_fwrite(texCoords, sizeof(MVector2), texCoordsSize, file); // colors M_fwrite(&colorsSize, sizeof(int), 1, file); if(colorsSize > 0) M_fwrite(colors, sizeof(MColor), colorsSize, file); // mapChannels { unsigned int size = mapChannelOffsets->size(); M_fwrite(&size, sizeof(int), 1, file); map<unsigned int, unsigned int>::iterator mit (mapChannelOffsets->begin()), mend(mapChannelOffsets->end()); for(;mit!=mend;++mit) { M_fwrite(&mit->first, sizeof(int), 1, file); M_fwrite(&mit->second, sizeof(int), 1, file); } } // Skins state = skin != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(skin) { // skin point unsigned int p, pointsNumber = skin->getPointsNumber(); M_fwrite(&pointsNumber, sizeof(int), 1, file); for(p=0; p<pointsNumber; p++) { MSkinPoint * skinPoint = skin->getPoint(p); unsigned int vertexId = skinPoint->getVertexId(); unsigned int bonesNumber = skinPoint->getBonesNumber(); unsigned short * bonesIds = skinPoint->getBonesIds(); float * bonesWeights = skinPoint->getBonesWeights(); // data M_fwrite(&vertexId, sizeof(int), 1, file); M_fwrite(&bonesNumber, sizeof(int), 1, file); if(bonesNumber > 0) { M_fwrite(bonesIds, sizeof(short), bonesNumber, file); M_fwrite(bonesWeights, sizeof(float), bonesNumber, file); } } } // Displays unsigned int d, displaysNumber = subMesh->getDisplaysNumber(); M_fwrite(&displaysNumber, sizeof(int), 1, file); for(d=0; d<displaysNumber; d++) { MDisplay * display = subMesh->getDisplay(d); M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); MMaterial * material = display->getMaterial(); M_CULL_MODES cullMode = display->getCullMode(); int materialId = getMaterialId(mesh, material); // data M_fwrite(&primitiveType, sizeof(M_PRIMITIVE_TYPES), 1, file); M_fwrite(&begin, sizeof(int), 1, file); M_fwrite(&size, sizeof(int), 1, file); M_fwrite(&materialId, sizeof(int), 1, file); M_fwrite(&cullMode, sizeof(M_CULL_MODES), 1, file); } } } M_fclose(file); return true; }
void MFixedRenderer::drawDisplay(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices, MVector3 * normals, MColor * colors) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplay); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); render->setColor4(MVector4(1, 1, 1, 1)); // get material MMaterial * material = display->getMaterial(); { float opacity = material->getOpacity(); if(opacity <= 0.0f) return; // data M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector2 * texCoords = subMesh->getTexCoords(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // get properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_BLENDING_MODES blendMode = material->getBlendMode(); M_CULL_MODES cullMode = display->getCullMode(); MVector3 * diffuse = material->getDiffuse(); MVector3 * specular = material->getSpecular(); MVector3 * emit = material->getEmit(); float shininess = material->getShininess(); // get current fog color MVector3 currentFogColor; render->getFogColor(¤tFogColor); // set cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // texture passes unsigned int texturesPassNumber = MIN(8, material->getTexturesPassNumber()); // set blending mode render->setBlendingMode(blendMode); // alpha test if(blendMode != M_BLENDING_ALPHA && texturesPassNumber > 0) { MTexturePass * texturePass = material->getTexturePass(0); MTexture * texture = texturePass->getTexture(); if(texture) { if(texture->getTextureRef()->getComponents() > 3) render->setAlphaTest(0.5f); } } // set fog color depending on blending switch(blendMode) { case M_BLENDING_ADD: case M_BLENDING_LIGHT: render->setFogColor(MVector3(0, 0, 0)); break; case M_BLENDING_PRODUCT: render->setFogColor(MVector3(1, 1, 1)); break; } // fixed pipeline { // no FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // Normal if(normals) { render->enableNormalArray(); render->setNormalPointer(M_FLOAT, normals); } // Color if(colors) { render->disableLighting(); render->enableColorArray(); render->setColorPointer(M_UBYTE, 4, colors); } // Material render->setMaterialDiffuse(MVector4(diffuse->x, diffuse->y, diffuse->z, opacity)); render->setMaterialSpecular(MVector4(*specular)); render->setMaterialAmbient(MVector4()); render->setMaterialEmit(MVector4(*emit)); render->setMaterialShininess(shininess); // switch to texture matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_TEXTURE); else render->disableTexture(); // Textures int id = texturesPassNumber; for(unsigned int t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); if((! texture) || (! texCoords)) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); continue; } // texCoords unsigned int offset = 0; if(subMesh->isMapChannelExist(texturePass->getMapChannel())) offset = subMesh->getMapChannelOffset(texturePass->getMapChannel()); // texture id unsigned int textureId = 0; MTextureRef * texRef = texture->getTextureRef(); if(texRef) textureId = texRef->getTextureId(); // bind texture render->bindTexture(textureId, t); render->enableTexture(); render->setTextureCombineMode(texturePass->getCombineMode()); render->setTextureUWrapMode(texture->getUWrapMode()); render->setTextureVWrapMode(texture->getVWrapMode()); // texture matrix render->loadIdentity(); render->translate(MVector2(0.5f, 0.5f)); render->scale(*texture->getTexScale()); render->rotate(MVector3(0, 0, -1), texture->getTexRotate()); render->translate(MVector2(-0.5f, -0.5f)); render->translate(*texture->getTexTranslate()); // texture coords render->enableTexCoordArray(); render->setTexCoordPointer(M_FLOAT, 2, texCoords + offset); } // switch back to modelview matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_MODELVIEW); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else{ render->drawArray(primitiveType, begin, size); } // disable arrays render->disableVertexArray(); if(normals) render->disableNormalArray(); if(colors) render->disableColorArray(); // restore textures for(int t=(int)(id-1); t>=0; t--) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); render->setTextureCombineMode(M_TEX_COMBINE_MODULATE); render->setMatrixMode(M_MATRIX_TEXTURE); render->loadIdentity(); render->setMatrixMode(M_MATRIX_MODELVIEW); } } // restore fog and alpha test render->setFogColor(currentFogColor); if(blendMode != M_BLENDING_ALPHA) render->setAlphaTest(0.0f); // restore lighting if(colors) render->enableLighting(); } }