\n#pragma once\n#include "MyColor.h"\n#include <string>\n\nclass Material\n{\npublic:\n\tchar shaderType[20] = "";\n\tint shaderN = -1;\n\tint primitiveType = GL_TRIANGLES;\n\tMyColor uColor;\n\tint uTex0 = -1;\n\tint uTex1mask = -1;\n\tint uTex2nm = -1;\n\tint uTex3 = -1;\n\tint uTex1alphaChannelN = 3; \/\/default - alpha channel for mask\n\tint uTex1alphaNegative = 0; \/\/default - alpha channel not negative\n\tint uTex0translateChannelN = -1; \/\/translate tex0 to tex3 by channelN. Default -1 - don't translate\n\n\tint uAlphaBlending = 0; \/\/for semi-transparency\n\tfloat uAlphaFactor = 1; \/\/for semi-transparency\n\tfloat uAmbient = 0.4f; \/\/ambient light\n\t\/\/specular light parameters\n\tfloat uSpecularIntencity = 0.8f;\n\tfloat uSpecularMinDot = 0.8f;\n\tfloat uSpecularPowerOf = 20.0f;\n\n\tfloat lineWidth = 1;\n\tint zBuffer = 1;\n\tint zBufferUpdate = 1;\npublic:\n\tint pickShaderNumber() { return pickShaderNumber(this); };\n\tstatic int pickShaderNumber(Material* pMT);\n\tvoid setShaderType(std::string needType) { setShaderType(this, needType); };\n\tstatic void setShaderType(Material* pMT, std::string needType) { myStrcpy_s(pMT->shaderType, 20, (char*)needType.c_str()); };\n\tvoid clear() { clear(this); };\n\tstatic void clear(Material* pMT);\n\tint assignShader(std::string needType) { return assignShader(this, needType); };\n\tstatic int assignShader(Material* pMT, std::string needType);\n};\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n\u042d\u0442\u0438 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u043c DrawJob <\/strong>\u0434\u043b\u044f \u043f\u043e\u0434-\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0440\u0435\u043d\u0434\u0440\u0438\u043d\u0433\u0430. \u0424\u0443\u043d\u043a\u0446\u0438\u044f – executeDrawJob(..)<\/em>.<\/p>\n\n\n\n4. \u0417\u0430\u043c\u0435\u043d\u0438\u043c DrawJob.cpp <\/em>\u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n\n#include "DrawJob.h"\n#include "platform.h"\n#include "utils.h"\n#include "Shader.h"\n#include "Texture.h"\n\n\/\/static arrays (vectors) of all loaded DrawJobs, VBO ids\nstd::vector<DrawJob*> DrawJob::drawJobs;\nstd::vector<unsigned int> DrawJob::buffersIds;\n\nDrawJob::DrawJob() {\n\tdrawJobs.push_back(this);\n}\nDrawJob::~DrawJob() {\n\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);\n\tif (glVAOid > 0)\n\t\tglDeleteVertexArrays(1, &glVAOid);\n}\nint DrawJob::newBufferId() {\n\tunsigned int bufferId;\n\tglGenBuffers(1, &bufferId);\n\tbuffersIds.push_back(bufferId);\n\treturn (int)bufferId;\n}\nunsigned int activeVBOid;\nint DrawJob::buildVAOforShader(DrawJob* pDJ, int shaderN) {\n\t\/\/delete VAO if exists already\n\tif (pDJ->glVAOid > 0) {\n\t\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n\t\tglDeleteVertexArrays(1, &(pDJ->glVAOid));\n\t}\n\tglGenVertexArrays(1, &pDJ->glVAOid);\n\tglBindVertexArray(pDJ->glVAOid);\n\n\t\/\/open shader descriptor to access variables locations\n\tShader* pShader = Shader::shaders.at(pDJ->mt.shaderN);\n\n\tactiveVBOid = 0;\n\tattachAttribute(pShader->l_aPos, 3, &pDJ->aPos);\n\tattachAttribute(pShader->l_aNormal, 3, &pDJ->aNormal);\n\tattachAttribute(pShader->l_aTuv, 2, &pDJ->aTuv);\n\tattachAttribute(pShader->l_aTuv2, 2, &pDJ->aTuv2); \/\/for normal map\n\tattachAttribute(pShader->l_aTangent, 3, &pDJ->aTangent); \/\/for normal map\n\tattachAttribute(pShader->l_aBinormal, 3, &pDJ->aBinormal); \/\/for normal map\n\n\tif (pDJ->glEBOid > 0)\n\t\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pDJ->glEBOid);\n\n\tglBindVertexArray(0);\n\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);\n\tglBindBuffer(GL_ARRAY_BUFFER, 0);\n\treturn 1;\n}\n\nint DrawJob::attachAttribute(int varLocationInShader, int attributeSizeInFloats, AttribRef* pAR) {\n\tif (varLocationInShader < 0)\n\t\treturn 0; \/\/not used in this shader\n\tif (pAR->glVBOid == 0) {\n\t\tmylog("ERROR in DrawJob::attachAttribute, nk such attribute\/VBO\\n");\n\t\treturn -1;\n\t}\n\tglEnableVertexAttribArray(varLocationInShader);\n\tif (activeVBOid != pAR->glVBOid) {\n\t\tactiveVBOid = pAR->glVBOid;\n\t\t\/\/attach input stream data\n\t\tglBindBuffer(GL_ARRAY_BUFFER, activeVBOid);\n\t}\n\tglVertexAttribPointer(varLocationInShader, attributeSizeInFloats, GL_FLOAT, GL_FALSE, pAR->stride, (void*)(long)pAR->offset);\n\treturn 1;\n}\n\nint DrawJob::executeDrawJob(DrawJob* pDJ, float* uMVP, float* uMV3x3, float* uMM, float* uVectorToLight, float* uCameraPosition, float sizeUnitPixelsSize, Material* pMt) {\n\tif (pMt == NULL)\n\t\tpMt = &(pDJ->mt);\n\tglBindVertexArray(pDJ->glVAOid);\n\tShader* pShader = Shader::shaders.at(pMt->shaderN);\n\tglUseProgram(pShader->GLid);\n\t\/\/input uniforms\n\tglUniformMatrix4fv(pShader->l_uMVP, 1, GL_FALSE, (const GLfloat*)uMVP);\n\tif (pShader->l_uMV3x3 >= 0)\n\t\tglUniformMatrix3fv(pShader->l_uMV3x3, 1, GL_FALSE, (const GLfloat*)uMV3x3);\n\tif (pShader->l_uMM >= 0)\n\t\tglUniformMatrix4fv(pShader->l_uMM, 1, GL_FALSE, (const GLfloat*)uMM);\n\tif (pShader->l_uVectorToLight >= 0)\n\t\tglUniform3fv(pShader->l_uVectorToLight, 1, (const GLfloat*)uVectorToLight);\n\tif (pShader->l_uCameraPosition >= 0)\n\t\tglUniform3fv(pShader->l_uCameraPosition, 1, (const GLfloat*)uCameraPosition);\n\n\t\/\/attach textures\n\tif (pShader->l_uTex0 >= 0) {\n\t\tint textureId = Texture::getGLid(pMt->uTex0);\n\t\t\/\/pass textureId to shader program\n\t\tglActiveTexture(GL_TEXTURE0); \/\/ activate the texture unit first before binding texture\n\t\tglBindTexture(GL_TEXTURE_2D, textureId);\n\t\t\/\/ Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0. \n\t\tglUniform1i(pShader->l_uTex0, 0);\n\t}\n\tif (pShader->l_uTex1mask >= 0) {\n\t\tint textureId = Texture::getGLid(pMt->uTex1mask);\n\t\t\/\/pass textureId to shader program\n\t\tglActiveTexture(GL_TEXTURE1); \/\/ activate the texture unit first before binding texture\n\t\tglBindTexture(GL_TEXTURE_2D, textureId);\n\t\t\/\/ Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 1. \n\t\tglUniform1i(pShader->l_uTex1mask, 1);\n\t}\n\tif (pShader->l_uTex2nm >= 0) {\n\t\tint textureId = Texture::getGLid(pMt->uTex2nm);\n\t\t\/\/pass textureId to shader program\n\t\tglActiveTexture(GL_TEXTURE2); \/\/ activate the texture unit first before binding texture\n\t\tglBindTexture(GL_TEXTURE_2D, textureId);\n\t\t\/\/ Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 2. \n\t\tglUniform1i(pShader->l_uTex2nm, 2);\n\t}\n\tif (pShader->l_uTex0translateChannelN >= 0) {\n\t\tglUniform1i(pShader->l_uTex0translateChannelN, pMt->uTex0translateChannelN);\n\t\tif (pShader->l_uTex3 >= 0 && pMt->uTex3 >= 0) {\n\t\t\tint textureId = Texture::getGLid(pMt->uTex3);\n\t\t\t\/\/pass textureId to shader program\n\t\t\tglActiveTexture(GL_TEXTURE3); \/\/ activate the texture unit first before binding texture\n\t\t\tglBindTexture(GL_TEXTURE_2D, textureId);\n\t\t\t\/\/ Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 3. \n\t\t\tglUniform1i(pShader->l_uTex3, 3);\n\t\t}\n\t}\n\t\/\/material uniforms\n\tif (pShader->l_uTex1alphaChannelN >= 0)\n\t\tglUniform1i(pShader->l_uTex1alphaChannelN, pMt->uTex1alphaChannelN);\n\tif (pShader->l_uTex1alphaNegative >= 0)\n\t\tglUniform1i(pShader->l_uTex1alphaNegative, pMt->uTex1alphaNegative);\n\tif (pShader->l_uColor >= 0)\n\t\tglUniform4fv(pShader->l_uColor, 1, pMt->uColor.forGL());\n\tif (pShader->l_uAlphaFactor >= 0)\n\t\tglUniform1f(pShader->l_uAlphaFactor, pMt->uAlphaFactor);\n\tif (pShader->l_uAlphaBlending >= 0)\n\t\tglUniform1i(pShader->l_uAlphaBlending, pMt->uAlphaBlending);\n\tif (pShader->l_uAmbient >= 0)\n\t\tglUniform1f(pShader->l_uAmbient, pMt->uAmbient);\n\tif (pShader->l_uSpecularIntencity >= 0)\n\t\tglUniform1f(pShader->l_uSpecularIntencity, pMt->uSpecularIntencity);\n\tif (pShader->l_uSpecularMinDot >= 0)\n\t\tglUniform1f(pShader->l_uSpecularMinDot, pMt->uSpecularMinDot);\n\tif (pShader->l_uSpecularPowerOf >= 0)\n\t\tglUniform1f(pShader->l_uSpecularPowerOf, pMt->uSpecularPowerOf);\n\n\t\/\/adjust render settings\n\tif (lineWidthIsImportant(pMt->primitiveType)) {\n\t\tfloat lw = sizeUnitPixelsSize * pMt->lineWidth;\n\t\tglLineWidth(lw);\n\t}\n\n\tif (pMt->zBuffer > 0) {\n\t\tglEnable(GL_DEPTH_TEST);\n\t\tglDepthFunc(GL_LEQUAL);\n\t}\n\telse\n\t\tglDisable(GL_DEPTH_TEST);\n\n\tif (pMt->zBufferUpdate > 0)\n\t\tglDepthMask(GL_TRUE);\n\telse\n\t\tglDepthMask(GL_FALSE);\n\n\tif (pShader->l_uAlphaBlending >= 0 && pMt->uAlphaBlending > 0) {\n\t\tglEnable(GL_BLEND);\n\t\tglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\n\t}\n\telse\n\t\tglDisable(GL_BLEND);\n\n\t\/\/execute\n\tif (pDJ->glEBOid == 0) {\n\t\tglDrawArrays(pMt->primitiveType, 0, pDJ->pointsN);\n\t}\n\telse { \/\/use EBO\n\t\tglDrawElements(pMt->primitiveType, pDJ->pointsN, GL_UNSIGNED_SHORT, 0);\n\t}\n\tglBindVertexArray(0);\n\treturn 1;\n}\nint DrawJob::cleanUp() {\n\tint itemsN = drawJobs.size();\n\t\/\/delete all drawJobs\n\tfor (int i = 0; i < itemsN; i++) {\n\t\tDrawJob* pDJ = drawJobs.at(i);\n\t\tdelete pDJ;\n\t}\n\tdrawJobs.clear();\n\t\/\/delete Buffers\n\titemsN = buffersIds.size();\n\t\/\/delete all buffers\n\tfor (int i = 0; i < itemsN; i++) {\n\t\tunsigned int id = buffersIds.at(i);\n\t\tglDeleteBuffers(1, &id);\n\t}\n\tbuffersIds.clear();\n\n\treturn 1;\n}\nint DrawJob::setDesirableOffsetsForSingleVBO(DrawJob* pDJ, int* pStride, int shaderN, int VBOid) {\n\t\/\/sets desirable offsets and stride according to given shader needs\n\t\/\/assuming that we have 1 single VBO\n\tShader* pSh = Shader::shaders.at(shaderN);\n\tint stride = 0;\n\tpDJ->aPos.offset = 0; \/\/attribute o_aPos, always 0\n\tstride += sizeof(float) * 3; \/\/aPos size - 3 floats (x,y,z)\n\tif (pSh->l_aNormal >= 0) { \/\/attribute normal\n\t\tpDJ->aNormal.offset = stride;\n\t\tstride += sizeof(float) * 3;\n\t}\n\tif (pSh->l_aTuv >= 0) { \/\/attribute TUV (texture coordinates)\n\t\tpDJ->aTuv.offset = stride; \/\/attribute TUV (texture coordinates)\n\t\tstride += sizeof(float) * 2;\n\t}\n\tif (pSh->l_aTuv2 >= 0) { \/\/for normal map\n\t\tpDJ->aTuv2.offset = stride;\n\t\tstride += sizeof(float) * 2;\n\t}\n\tif (pSh->l_aTangent >= 0) { \/\/for normal map\n\t\tpDJ->aTangent.offset = stride;\n\t\tstride += sizeof(float) * 3;\n\t}\n\tif (pSh->l_aBinormal >= 0) { \/\/for normal map\n\t\tpDJ->aBinormal.offset = stride;\n\t\tstride += sizeof(float) * 3;\n\t}\n\t*pStride = stride;\n\t\/\/add stride and VBOid to all attributes\n\tAttribRef* pAR = NULL;\n\tpAR = &pDJ->aPos; pAR->glVBOid = VBOid; pAR->stride = stride;\n\tpAR = &pDJ->aNormal; pAR->glVBOid = VBOid; pAR->stride = stride;\n\tpAR = &pDJ->aTuv; pAR->glVBOid = VBOid; pAR->stride = stride;\n\tpAR = &pDJ->aTuv2; pAR->glVBOid = VBOid; pAR->stride = stride;\n\tpAR = &pDJ->aTangent; pAR->glVBOid = VBOid; pAR->stride = stride;\n\tpAR = &pDJ->aBinormal; pAR->glVBOid = VBOid; pAR->stride = stride;\n\n\treturn 1;\n}\nbool DrawJob::lineWidthIsImportant(int primitiveType) {\n\tif (primitiveType == GL_TRIANGLES) return false;\n\tif (primitiveType == GL_TRIANGLE_STRIP) return false;\n\tif (primitiveType == GL_TRIANGLE_FAN) return false;\n\treturn true;\n}\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
\n\n\n\n\u0427\u0442\u0435\u043d\u0438\u0435\/\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 – \u0432 ModelLoader<\/em>-\u0435, \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fillProps_mt(..)<\/em>.<\/p>\n\n\n\n5. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n\n#include "ModelLoader.h"\n#include "platform.h"\n#include "TheGame.h"\n#include "DrawJob.h"\n#include "Texture.h"\n#include "utils.h"\n#include "Polygon.h"\n\nextern TheGame theGame;\n\nint ModelLoader::loadModel(std::vector<GameSubj*>* pSubjsVector0, std::string sourceFile, std::string subjClass) {\n\t\/\/returns element's (Subj) number or -1\n\tint subjN = pSubjsVector0->size();\n\tGameSubj* pGS = theGame.newGameSubj(subjClass);\n\tpSubjsVector0->push_back(pGS);\n\t\/\/pGS->djStartN = DrawJob::drawJobs.size();\n\tModelLoader* pML = new ModelLoader(pSubjsVector0, subjN, NULL, sourceFile);\n\tprocessSource(pML);\n\tdelete pML;\n\t\/\/pGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\treturn subjN;\n}\n\nint ModelLoader::setValueFromIntHashMap(int* pInt, std::map<std::string, int> intHashMap, std::string varName, std::string tagStr) {\n\tif (!varExists(varName, tagStr))\n\t\treturn 0;\n\tstd::string str0 = getStringValue(varName, tagStr);\n\tif (intHashMap.find(str0) == intHashMap.end()) {\n\t\tmylog("ERROR in ModelLoader::setValueFromIntMap, %s not found, %s\\n", varName.c_str(), tagStr.c_str());\n\t\treturn -1;\n\t}\n\t*pInt = intHashMap[getStringValue(varName, tagStr)];\n\treturn 1;\n}\nint ModelLoader::setTexture(ModelLoader* pML, int* pInt, std::string txName) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tbool resetTexture = false;\n\tstd::string varName = txName + "_use";\n\tif (varExists(varName, pML->currentTag)) {\n\t\tif (setValueFromIntHashMap(pInt, pMB->texturesHashMap, varName, pML->currentTag) == 0) {\n\t\t\tmylog("ERROR in ModelLoader::setTexture: texture not in hashMap: %s\\n", pML->currentTag.c_str());\n\t\t\treturn -1;\n\t\t}\n\t\tresetTexture = true;\n\t}\n\telse{\n\t\tvarName = txName + "_src";\n\t\tif (varExists(varName, pML->currentTag)) {\n\t\t\tstd::string txFile = getStringValue(varName, pML->currentTag);\n\t\t\tvarName = txName + "_ckey";\n\t\t\tunsigned int intCkey = 0;\n\t\t\tsetUintColorValue(&intCkey, varName, pML->currentTag);\n\t\t\t*pInt = Texture::loadTexture(buildFullPath(pML, txFile), intCkey);\n\t\t\tresetTexture = true;\n\t\t}\n\t}\n\tif(resetTexture)\n\t\treturn 1;\n\treturn 0; \/\/texture wasn't reset\n}\nint ModelLoader::setMaterialTextures(ModelLoader* pML, Material* pMT) {\n\tif (setTexture(pML, &pMT->uTex0, "uTex0") > 0)\n\t\tpMT->uColor.clear();\n\tsetTexture(pML, &pMT->uTex1mask, "uTex1mask");\n\tsetTexture(pML, &pMT->uTex2nm, "uTex2nm");\n\tsetTexture(pML, &pMT->uTex3, "uTex3");\n\treturn 1;\n}\nint ModelLoader::fillProps_mt(Material* pMT, std::string tagStr, ModelLoader* pML) {\n\tsetCharsValue(pMT->shaderType, 20, "mt_type", tagStr);\n\tsetMaterialTextures(pML, pMT);\n\t\/\/color\n\tif (varExists("uColor", tagStr)) {\n\t\tunsigned int uintColor = 0;\n\t\tsetUintColorValue(&uintColor, "uColor", tagStr);\n\t\tpMT->uColor.setUint32(uintColor);\n\t\tpMT->uTex0 = -1;\n\t}\n\t\/\/mylog("mt.uTex0=%d, mt.uTex1mask=%d\\n", mt.uTex0, mt.uTex1mask);\n\tif (varExists("primitiveType", tagStr)) {\n\t\tstd::string str0 = getStringValue("primitiveType", tagStr);\n\t\tif (str0.compare("GL_POINTS") == 0) pMT->primitiveType = GL_POINTS;\n\t\telse if (str0.compare("GL_LINES") == 0) pMT->primitiveType = GL_LINES;\n\t\telse if (str0.compare("GL_LINE_STRIP") == 0) pMT->primitiveType = GL_LINE_STRIP;\n\t\telse if (str0.compare("GL_LINE_LOOP") == 0) pMT->primitiveType = GL_LINE_LOOP;\n\t\telse if (str0.compare("GL_TRIANGLE_STRIP") == 0) pMT->primitiveType = GL_TRIANGLE_STRIP;\n\t\telse if (str0.compare("GL_TRIANGLE_FAN") == 0) pMT->primitiveType = GL_TRIANGLE_FAN;\n\t\telse pMT->primitiveType = GL_TRIANGLES;\n\t}\n\tsetIntValue(&pMT->uTex1alphaChannelN, "uTex1alphaChannelN", tagStr);\n\tsetIntValue(&pMT->uTex0translateChannelN, "uTex0translateChannelN", tagStr);\n\tsetFloatValue(&pMT->uAlphaFactor, "uAlphaFactor", tagStr);\n\tif (pMT->uAlphaFactor < 1)\n\t\tpMT->uAlphaBlending = 1;\n\tsetIntBoolValue(&pMT->uAlphaBlending, "uAlphaBlending", tagStr);\n\tif (pMT->uAlphaBlending > 0)\n\t\tpMT->zBufferUpdate = 0;\n\tsetFloatValue(&pMT->uAmbient, "uAmbient", tagStr);\n\tsetFloatValue(&pMT->uSpecularIntencity, "uSpecularIntencity", tagStr);\n\tsetFloatValue(&pMT->uSpecularMinDot, "uSpecularMinDot", tagStr);\n\tsetFloatValue(&pMT->uSpecularPowerOf, "uSpecularPowerOf", tagStr);\n\n\tsetFloatValue(&pMT->lineWidth, "lineWidth", tagStr);\n\tsetIntBoolValue(&pMT->zBuffer, "zBuffer", tagStr);\n\tif (pMT->zBuffer < 1)\n\t\tpMT->zBufferUpdate = 0;\n\tsetIntBoolValue(&pMT->zBufferUpdate, "zBufferUpdate", tagStr);\n\n\treturn 1;\n}\nint ModelLoader::processTag(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tif (pML->tagName.compare("texture_as") == 0) {\n\t\t\/\/saves texture N in texturesMap under given name\n\t\tstd::string keyName = getStringValue("texture_as", pML->currentTag);\n\t\tif (pMB->texturesHashMap.find(keyName) != pMB->texturesHashMap.end())\n\t\t\treturn pMB->texturesHashMap[keyName];\n\t\telse { \/\/add new\n\t\t\tstd::string txFile = getStringValue("src", pML->currentTag);\n\t\t\tunsigned int intCkey = 0;\n\t\t\tsetUintColorValue(&intCkey, "ckey", pML->currentTag);\n\t\t\tint txN = Texture::loadTexture(buildFullPath(pML, txFile), intCkey);\n\t\t\tpMB->texturesHashMap[keyName] = txN;\n\t\t\t\/\/mylog("%s=%d\\n", keyName.c_str(), pMB->texturesMap[keyName]);\n\t\t\treturn txN;\n\t\t}\n\t}\n\tif (pML->tagName.compare("mt_type") == 0) {\n\t\t\/\/sets current material\n\t\tModelBuilder* pMB = pML->pModelBuilder;\n\t\tif (!pML->closedTag) {\n\t\t\t\/\/save previous material in stack\n\t\t\tif (pMB->usingMaterialN >= 0)\n\t\t\t\tpMB->materialsStack.push_back(pMB->usingMaterialN);\n\t\t}\n\t\tMaterial mt;\n\t\tfillProps_mt(&mt, pML->currentTag, pML);\n\t\tpMB->usingMaterialN = pMB->getMaterialN(pMB, &mt);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/mt_type") == 0) {\n\t\t\/\/restore previous material\n\t\tif (pMB->materialsStack.size() > 0) {\n\t\t\tpMB->usingMaterialN = pMB->materialsStack.back();\n\t\t\tpMB->materialsStack.pop_back();\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("vs") == 0) {\n\t\t\/\/sets virtual shape\n\t\tModelBuilder* pMB = pML->pModelBuilder;\n\t\tif (pML->closedTag) {\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tdelete pMB->pCurrentVShape;\n\t\t}\n\t\telse { \/\/open tag\n\t\t\t\/\/save previous vshape in stack\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tpMB->vShapesStack.push_back(pMB->pCurrentVShape);\n\t\t}\n\t\tpMB->pCurrentVShape = new VirtualShape();\n\t\tfillProps_vs(pMB->pCurrentVShape, pML->currentTag);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/vs") == 0) {\n\t\t\/\/restore previous virtual shape\n\t\tif (pMB->vShapesStack.size() > 0) {\n\t\t\tif (pMB->pCurrentVShape != NULL)\n\t\t\t\tdelete(pMB->pCurrentVShape);\n\t\t\tpMB->pCurrentVShape = pMB->vShapesStack.back();\n\t\t\tpMB->vShapesStack.pop_back();\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("group") == 0) {\n\t\tstd::string notAllowed[] = { "pxyz","axyz","align","headTo" };\n\t\tint notAllowedLn = sizeof(notAllowed) \/ sizeof(notAllowed[0]);\n\t\tfor (int i = 0; i < notAllowedLn; i++)\n\t\t\tif (varExists(notAllowed[i], pML->currentTag)) {\n\t\t\t\tmylog("ERROR in ModelLoader::processTag: use %s in <\/group>: %s\\n", notAllowed[i].c_str(), pML->currentTag.c_str());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\tpMB->lockGroup(pMB);\n\t\t\/\/mark\n\t\tif (varExists("mark", pML->currentTag))\n\t\t\taddMark(pMB->pCurrentGroup->marks, getStringValue("mark", pML->currentTag));\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/group") == 0) {\n\t\tGroupTransform gt;\n\t\tfillProps_gt(>, pMB, pML->currentTag);\n\t\tgt.executeGroupTransform(pMB);\n\n\t\tpMB->releaseGroup(pMB);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("a") == 0)\n\t\treturn processTag_a(pML); \/\/apply \n\tif (pML->tagName.compare("clone") == 0)\n\t\treturn processTag_clone(pML);\n\tif (pML->tagName.compare("\/clone") == 0)\n\t\treturn processTag_clone(pML);\n\tif (pML->tagName.compare("do") == 0)\n\t\treturn processTag_do(pML);\n\tif (pML->tagName.compare("a2mesh") == 0)\n\t\treturn processTag_a2mesh(pML);\n\tif (pML->tagName.compare("mt_adjust") == 0) {\n\t\tif (pML->pMaterialAdjust != NULL)\n\t\t\tmylog("ERROR in ModelLoader::processTag %s, pMaterialAdjust is still busy. File: %s\\n", pML->currentTag.c_str(), pML->fullPath.c_str());\n\t\tpML->pMaterialAdjust = new (MaterialAdjust);\n\t\tfillProps_mt(pML->pMaterialAdjust, pML->currentTag, pML);\n\t\tpML->pMaterialAdjust->setWhat2adjust(pML->pMaterialAdjust, pML->currentTag);\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/mt_adjust") == 0) {\n\t\tif (pML->pMaterialAdjust != NULL) {\n\t\t\tdelete pML->pMaterialAdjust;\n\t\t\tpML->pMaterialAdjust = NULL;\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("line") == 0) {\n\t\tMaterial mt;\n\t\t\/\/save previous material in stack\n\t\tif (pMB->usingMaterialN >= 0){\n\t\t\tpMB->materialsStack.push_back(pMB->usingMaterialN);\n\t\t\tmemcpy(&mt, pMB->materialsList.at(pMB->usingMaterialN),sizeof(Material));\n\t\t}\n\t\tmt.primitiveType = GL_LINE_STRIP;\n\t\tfillProps_mt(&mt, pML->currentTag, pML);\n\t\tpMB->usingMaterialN = pMB->getMaterialN(pMB, &mt);\n\t\t\/\/line starts\n\t\tpML->lineStartsAt = pMB->vertices.size();\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("\/line") == 0) {\n\t\tpMB->vertices.back()->endOfSequence = 1;\n\t\tpML->lineStartsAt = -1;\n\t\t\/\/restore previous material\n\t\tif (pMB->materialsStack.size() > 0) {\n\t\t\tpMB->usingMaterialN = pMB->materialsStack.back();\n\t\t\tpMB->materialsStack.pop_back();\n\t\t}\n\t\treturn 1;\n\t}\n\tif (pML->tagName.compare("p") == 0) {\n\t\t\/\/line point\n\t\tVertex01* pV = new Vertex01();\n\t\tif (pMB->vertices.size() > pML->lineStartsAt)\n\t\t\tmemcpy(pV, pMB->vertices.back(), sizeof(Vertex01));\n\t\tpV->subjN = pMB->usingSubjN;\n\t\tpV->materialN = pMB->usingMaterialN;\n\t\tsetFloatArray(pV->aPos, 3, "pxyz", pML->currentTag);\n\t\tsetFloatValue(&pV->aPos[0], "px", pML->currentTag);\n\t\tsetFloatValue(&pV->aPos[1], "py", pML->currentTag);\n\t\tsetFloatValue(&pV->aPos[2], "pz", pML->currentTag);\n\t\tfloat dPos[3] = { 0,0,0 };\n\t\tsetFloatArray(dPos, 3, "dxyz", pML->currentTag);\n\t\tsetFloatValue(&dPos[0], "dx", pML->currentTag);\n\t\tsetFloatValue(&dPos[1], "dy", pML->currentTag);\n\t\tsetFloatValue(&dPos[2], "dz", pML->currentTag);\n\t\tif (!v3equals(dPos, 0))\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t\tpV->aPos[i] += dPos[i];\n\t\tpMB->vertices.push_back(pV);\n\t\treturn 1;\n\t}\n\tmylog("ERROR in ModelLoader::processTag, unhandled tag %s, file %s\\n", pML->currentTag.c_str(), pML->fullPath.c_str());\n\treturn -1;\n}\n\nint ModelLoader::fillProps_vs(VirtualShape* pVS, std::string tagStr) {\n\t\/\/sets virtual shape\n\tsetCharsValue(pVS->shapeType, 20, "vs", tagStr);\n\tsetFloatArray(pVS->whl, 3, "whl", tagStr);\n\t\/\/extensions\n\tfloat ext;\n\tif (varExists("ext", tagStr)) {\n\t\tsetFloatValue(&ext, "ext", tagStr);\n\t\tpVS->setExt(ext);\n\t}\n\tif (varExists("extX", tagStr)) {\n\t\tsetFloatValue(&ext, "extX", tagStr);\n\t\tpVS->setExtX(ext);\n\t}\n\tif (varExists("extY", tagStr)) {\n\t\tsetFloatValue(&ext, "extY", tagStr);\n\t\tpVS->setExtY(ext);\n\t}\n\tif (varExists("extZ", tagStr)) {\n\t\tsetFloatValue(&ext, "extZ", tagStr);\n\t\tpVS->setExtZ(ext);\n\t}\n\tsetFloatValue(&pVS->extU, "extU", tagStr);\n\tsetFloatValue(&pVS->extD, "extD", tagStr);\n\tsetFloatValue(&pVS->extL, "extL", tagStr);\n\tsetFloatValue(&pVS->extR, "extR", tagStr);\n\tsetFloatValue(&pVS->extF, "extF", tagStr);\n\tsetFloatValue(&pVS->extB, "extB", tagStr);\n\t\/\/sections\n\tsetIntValue(&pVS->sectionsR, "sectR", tagStr);\n\tsetIntValue(&pVS->sections[0], "sectX", tagStr);\n\tsetIntValue(&pVS->sections[1], "sectY", tagStr);\n\tsetIntValue(&pVS->sections[2], "sectZ", tagStr);\n\n\t\/\/mylog("pVS->shapeType=%s whl=%fx%fx%f\\n", pVS->shapeType, pVS->whl[0], pVS->whl[1], pVS->whl[2]);\n\treturn 1;\n}\nint ModelLoader::processTag_a(ModelLoader* pML) {\n\t\/\/apply\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tstd::string tagStr = pML->currentTag;\n\tpMB->lockGroup(pMB);\n\t\/\/mark\n\tif (varExists("mark", tagStr))\n\t\taddMark(pMB->pCurrentGroup->marks, getStringValue("mark", tagStr));\n\n\tstd::vector<std::string> applyTosVector = splitString(pML->getStringValue("a", tagStr), ",");\n\tMaterial* pMT = pMB->materialsList.at(pMB->usingMaterialN);\n\tint texN = pMT->uTex1mask;\n\tif (texN < 0)\n\t\ttexN = pMT->uTex0;\n\tfloat xywh[4] = { 0,0,1,1 };\n\tTexCoords* pTC = NULL;\n\tif (varExists("xywh", tagStr)) {\n\t\tsetFloatArray(xywh, 4, "xywh", tagStr);\n\t\tstd::string flipStr = getStringValue("flip", tagStr);\n\t\tTexCoords tc;\n\t\ttc.set(texN, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\tpTC = &tc;\n\t}\n\tTexCoords* pTC2nm = NULL;\n\tif (varExists("xywh2nm", tagStr)) {\n\t\tsetFloatArray(xywh, 4, "xywh2nm", tagStr);\n\t\tstd::string flipStr = getStringValue("flip2nm", tagStr);\n\t\tTexCoords tc2nm;\n\t\ttc2nm.set(pMT->uTex2nm, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\tpTC2nm = &tc2nm;\n\t}\n\t\/\/adjusted VirtualShape\n\tVirtualShape* pVS_a = new VirtualShape(*pMB->pCurrentVShape);\n\tfillProps_vs(pVS_a, tagStr);\n\n\tfor (int aN = 0; aN < (int)applyTosVector.size(); aN++) {\n\t\tpMB->buildFace(pMB, applyTosVector.at(aN), pVS_a, pTC, pTC2nm);\n\t}\n\tdelete pVS_a;\n\t\/\/mylog("vertsN=%d\\n",pMB->vertices.size());\n\n\tGroupTransform GT_a;\n\tfillProps_gt(>_a, pMB, tagStr);\n\tGT_a.executeGroupTransform(pMB);\n\n\tpMB->releaseGroup(pMB);\n\treturn 1;\n}\nint ModelLoader::processTag_clone(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tif (pML->tagName.compare("clone") == 0) {\n\t\t\/\/mark what to clone\n\t\tGroupTransform gt;\n\t\tgt.pGroup = pMB->pLastClosedGroup;\n\t\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\n\t\t\/\/cloning\n\t\tpMB->lockGroup(pMB);\n\t\tgt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &pMB->vertices, &pMB->triangles);\n\t}\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.executeGroupTransform(pMB);\n\n\tif (pML->tagName.compare("\/clone") == 0 || pML->closedTag) {\n\t\tpMB->releaseGroup(pMB);\n\t}\n\treturn 1;\n}\nint ModelLoader::addMark(char* marks, std::string newMark) {\n\tif (newMark.empty())\n\t\treturn 0;\n\tstd::string allMarks;\n\tallMarks.assign(marks);\n\tallMarks.append("<" + newMark + ">");\n\tmyStrcpy_s(marks, 124, allMarks.c_str());\n\treturn 1;\n}\nint ModelLoader::fillProps_gt(GroupTransform* pGT, ModelBuilder* pMB, std::string tagStr) {\n\tpGT->pGroup = pMB->pCurrentGroup;\n\t\/\/position\n\tsetFloatArray(pGT->shift, 3, "pxyz", tagStr);\n\tsetFloatValue(&pGT->shift[0], "px", tagStr);\n\tsetFloatValue(&pGT->shift[1], "py", tagStr);\n\tsetFloatValue(&pGT->shift[2], "pz", tagStr);\n\t\/\/angles\n\tsetFloatArray(pGT->spin, 3, "axyz", tagStr);\n\tsetFloatValue(&pGT->spin[0], "ax", tagStr);\n\tsetFloatValue(&pGT->spin[1], "ay", tagStr);\n\tsetFloatValue(&pGT->spin[2], "az", tagStr);\n\t\/\/scale\n\tsetFloatArray(pGT->scale, 3, "scale", tagStr);\n\n\tpGT->onThe = getStringValue("onThe", tagStr);\n\tpGT->allign = getStringValue("allign", tagStr);\n\tpGT->headZto = getStringValue("headZto", tagStr);\n\t\/\/limit to\n\tif (varExists("all", tagStr))\n\t\tpGT->pGroup = NULL;\n\tif (varExists("lastClosedGroup", tagStr))\n\t\tpGT->pGroup = pMB->pLastClosedGroup;\n\tif (varExists("markedAs", tagStr))\n\t\tpGT->limit2mark(pGT, getStringValue("markedAs", tagStr));\n\tsetFloatArray(pGT->pMin, 3, "xyzMin", tagStr);\n\tsetFloatArray(pGT->pMax, 3, "xyzMax", tagStr);\n\n\tif (varExists("sizeD", tagStr)) { \/\/re-size\n\t\tfloat sizeD[3];\n\t\tsetFloatArray(sizeD, 3, "sizeD", tagStr);\n\t\t\/\/bounding box\n\t\tpGT->flagSelection(pGT, &pMB->vertices, NULL);\n\t\tfloat bbMin[3];\n\t\tfloat bbMax[3];\n\t\tpGT->buildBoundingBoxFlagged(bbMin, bbMax, &pMB->vertices);\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tfloat size = bbMax[i] - bbMin[i];\n\t\t\tpGT->scale[i] = (size + sizeD[i]) \/ size;\n\t\t}\n\t}\n\treturn 1;\n}\nint ModelLoader::processTag_do(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\tgt.transformFlagged(>, &pMB->vertices);\n\treturn 1;\n}\nint ModelLoader::processTag_a2mesh(ModelLoader* pML) {\n\tModelBuilder* pMB = pML->pModelBuilder;\n\tstd::string tagStr = pML->currentTag;\n\tGroupTransform gt;\n\tfillProps_gt(>, pMB, pML->currentTag);\n\tgt.flagSelection(>, &pMB->vertices, &pMB->triangles);\n\t\/\/clone a copy\n\tstd::vector<Vertex01*> vx1;\n\tstd::vector<Triangle01*> tr1;\n\tgt.cloneFlagged(NULL, &vx1, &tr1, &pMB->vertices, &pMB->triangles);\n\t\/\/ build transform and inverted martrices\n\tmat4x4 transformMatrix;\n\tgt.buildTransformMatrix(>, &transformMatrix);\n\tmat4x4 transformMatrixInverted;\n\tmat4x4_invert(transformMatrixInverted, transformMatrix);\n\t\/\/move\/rotate cloned\n\tgt.flagAll(&vx1, &tr1);\n\t\/\/gt.transformFlagged(&pMB->vertices, &transformMatrixInverted);\n\tgt.transformFlaggedMx(&vx1, &transformMatrixInverted);\n\n\t\/\/gt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &vx1, &tr1);\n\n\tfloat wh[2];\n\tsetFloatArray(wh, 2, "wh", tagStr);\n\tPolygon frame;\n\tframe.setRectangle(&frame, wh[0], wh[1]);\n\t\/\/destination arrays\n\tstd::vector<Vertex01*> vx2;\n\tstd::vector<Triangle01*> tr2;\n\tPolygon triangle;\n\tfor (int i = tr1.size() - 1; i >= 0; i--) {\n\t\ttriangle.setTriangle(&triangle, tr1.at(i), &vx1);\n\t\tPolygon intersection;\n\t\tint pointsN = Polygon::xyIntersection(&intersection, &frame, &triangle);\n\t\tif (pointsN > 2) {\n\t\t\tPolygon::buildTriangles(&intersection);\n\t\t\tGroupTransform::flagAll(&intersection.vertices, &intersection.triangles);\n\t\t\tGroupTransform::cloneFlagged(NULL, &vx2, &tr2, &intersection.vertices, &intersection.triangles);\n\t\t}\n\t}\n\tgt.flagAll(&vx2, &tr2);\n\t\/\/at this point we have cutted fragment facing us\n\tint vxTotal = vx2.size();\n\tint trTotal = tr2.size();\n\t\/\/apply adjusted material ?\n\tif (pML->pMaterialAdjust != NULL) {\n\t\t\/\/scan vertices to find new (unupdated) material\n\t\tint materialNsrc = -1; \/\/which N to replace\n\t\tint materialNdst = -1; \/\/replace by N \n\t\tfor (int vN = 0; vN < vxTotal; vN++) {\n\t\t\tVertex01* pV = vx2.at(vN);\n\t\t\tif (pV->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tif (materialNsrc == pV->materialN)\n\t\t\t\tcontinue;\n\t\t\t\/\/have new material\n\t\t\tmaterialNsrc = pV->materialN;\n\t\t\tMaterial mt;\n\t\t\tMaterial* pMt0 = pMB->materialsList.at(materialNsrc);\n\t\t\tmemcpy(&mt, pMt0, sizeof(Material));\n\t\t\t\/\/modify material\n\t\t\tMaterialAdjust::adjust(&mt, pML->pMaterialAdjust);\n\t\t\tmaterialNdst = pMB->getMaterialN(pMB, &mt);\n\t\t\tif (materialNsrc != materialNdst) {\n\t\t\t\t\/\/replace mtN in vx and tr arrays\n\t\t\t\tfor (int vN2 = vN; vN2 < vxTotal; vN2++) {\n\t\t\t\t\tVertex01* pV2 = vx2.at(vN2);\n\t\t\t\t\tif (pV2->flag < 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (materialNsrc == pV2->materialN)\n\t\t\t\t\t\tpV2->materialN = materialNdst;\n\t\t\t\t}\n\t\t\t\tfor (int tN2 = 0; tN2 < trTotal; tN2++) {\n\t\t\t\t\tTriangle01* pT2 = tr2.at(tN2);\n\t\t\t\t\tif (pT2->flag < 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (materialNsrc == pT2->materialN)\n\t\t\t\t\t\tpT2->materialN = materialNdst;\n\t\t\t\t}\n\t\t\t\tmaterialNsrc = materialNdst;\n\t\t\t}\n\t\t}\n\t}\n\telse { \/\/ pML->pMaterialAdjust == NULL, use pMB->usingMaterialN\n\t\tfor (int vN2 = 0; vN2 < vxTotal; vN2++) {\n\t\t\tVertex01* pV2 = vx2.at(vN2);\n\t\t\tif (pV2->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tpV2->materialN = pMB->usingMaterialN;\n\t\t}\n\t\tfor (int tN2 = 0; tN2 < trTotal; tN2++) {\n\t\t\tTriangle01* pT2 = tr2.at(tN2);\n\t\t\tif (pT2->flag < 0)\n\t\t\t\tcontinue;\n\t\t\tpT2->materialN = pMB->usingMaterialN;\n\t\t}\n\t}\n\t\/\/apply xywh\/2nm ?\n\tif (varExists("xywh", tagStr) || varExists("xywh2nm", tagStr)) {\n\t\tMaterial* pMT = pMB->materialsList.at(vx2.at(0)->materialN);\n\t\tfloat xywh[4] = { 0,0,1,1 };\n\t\tTexCoords* pTC = NULL;\n\t\tif (varExists("xywh", tagStr)) {\n\t\t\tsetFloatArray(xywh, 4, "xywh", tagStr);\n\t\t\tstd::string flipStr = getStringValue("flip", tagStr);\n\t\t\tint texN = pMT->uTex1mask;\n\t\t\tif (texN < 0)\n\t\t\t\ttexN = pMT->uTex0;\n\t\t\tTexCoords tc;\n\t\t\ttc.set(texN, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\t\tpTC = &tc;\n\t\t}\n\t\tTexCoords* pTC2nm = NULL;\n\t\tif (varExists("xywh2nm", tagStr)) {\n\t\t\tsetFloatArray(xywh, 4, "xywh2nm", tagStr);\n\t\t\tstd::string flipStr = getStringValue("flip2nm", tagStr);\n\t\t\tTexCoords tc2nm;\n\t\t\ttc2nm.set(pMT->uTex2nm, xywh[0], xywh[1], xywh[2], xywh[3], flipStr);\n\t\t\tpTC2nm = &tc2nm;\n\t\t}\n\t\tpMB->applyTexture2flagged(&vx2, "front", pTC, false);\n\t\tpMB->applyTexture2flagged(&vx2, "front", pTC2nm, true);\n\t}\n\n\tfloat detachBy =0;\n\tsetFloatValue(&detachBy, "detachBy", tagStr);\n\tif (detachBy != 0) {\n\t\tmat4x4 mx;\n\t\tmat4x4_translate(mx, 0, 0, detachBy);\n\t\tgt.transformFlaggedMx(&vx2, &mx);\n\t}\n\t\/\/move\/rotate back\n\tgt.transformFlaggedMx(&vx2, &transformMatrix);\n\t\/\/clone back to modelBuilder arrays\n\tgt.cloneFlagged(pMB, &pMB->vertices, &pMB->triangles, &vx2, &tr2);\n\n\t\/\/clear memory\n\tfor (int i = vx1.size() - 1; i >= 0; i--)\n\t\tdelete vx1.at(i);\n\tvx1.clear();\n\tfor (int i = tr1.size() - 1; i >= 0; i--)\n\t\tdelete tr1.at(i);\n\ttr1.clear();\n\tfor (int i = vx2.size() - 1; i >= 0; i--)\n\t\tdelete vx2.at(i);\n\tvx2.clear();\n\tfor (int i = tr2.size() - 1; i >= 0; i--)\n\t\tdelete tr2.at(i);\n\ttr2.clear();\n\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
- \u0414\u0440\u0443\u0433\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0443\u0442 – \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 detachBy<\/em> \u0434\u043b\u044f \u0442\u0430\u0433\u0430 a2mesh <\/em>(\u0441\u0442\u0440\u043e\u043a\u0438 562-568).<\/li><\/ul>\n\n\n\n
\n\n\n\nTheGame.cpp <\/em>\u0442\u043e\u0436\u0435 \u0437\u0430\u0434\u0435\u0442. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c z-buffer \u0434\u043b\u044f \u043a\u0430\u043a\u0438\u0445-\u0442\u043e DrawJobs<\/em>, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d \u0432\u043a\u043b\u044e\u0447\u0435\u043d<\/strong> \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0447\u0438\u0441\u0442\u0438\u0442\u044c z-buffer (\u0441\u0442\u0440\u043e\u043a\u0430 50).<\/p>\n\n\n\n 6.\u0417\u0430\u043c\u0435\u043d\u0438\u043c TheGame.cpp<\/em> \u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n\n#include "TheGame.h"\n#include "platform.h"\n#include "utils.h"\n#include "linmath.h"\n#include "Texture.h"\n#include "Shader.h"\n#include "DrawJob.h"\n#include "ModelBuilder.h"\n#include "TexCoords.h"\n#include "ModelLoader.h"\n\nextern std::string filesRoot;\nextern float degrees2radians;\n\nstd::vector<GameSubj*> TheGame::gameSubjs;\n\nint TheGame::getReady() {\n bExitGame = false;\n Shader::loadShaders();\n glEnable(GL_CULL_FACE);\n\n glEnable(GL_DEPTH_TEST);\n glDepthFunc(GL_LEQUAL);\n glDepthMask(GL_TRUE);\n\n int subjN = ModelLoader::loadModel(&gameSubjs, "\/dt\/models\/misc\/marlboro01\/root01.txt", "");\n GameSubj* pGS = gameSubjs.at(subjN);\n pGS->name.assign("box1");\n pGS->ownSpeed.setDegrees(1.5, 1, 0.5);\n pGS->ownCoords.setDegrees(0,30, 0);\n\n \/\/===== set up camera\n mainCamera.ownCoords.setDegrees(15, 180, 0); \/\/set camera angles\/orientation\n mainCamera.viewRangeDg = 20;\n mainCamera.stageSize[0] = 80;\n mainCamera.stageSize[1] = 120;\n memcpy(mainCamera.lookAtPoint, pGS->ownCoords.pos, sizeof(float) * 3);\n mainCamera.onScreenResize();\n\n \/\/===== set up light\n v3set(dirToMainLight, -1, 1, 1);\n vec3_norm(dirToMainLight, dirToMainLight);\n\n return 1;\n}\nint TheGame::drawFrame() {\n myPollEvents(); \n\n \/\/glClearColor(0.0, 0.0, 0.5, 1.0);\n glDepthMask(GL_TRUE);\n glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n\n mat4x4 mProjection, mViewProjection, mMVP, mMV4x4;\n \/\/mat4x4_ortho(mProjection, -(float)screenSize[0] \/ 2, (float)screenSize[0] \/ 2, -(float)screenSize[1] \/ 2, (float)screenSize[1] \/ 2, 100.f, 500.f);\n float nearClip = mainCamera.focusDistance - 55;\n float farClip = mainCamera.focusDistance + 55;\n if (nearClip < 0) nearClip = 0;\n mat4x4_perspective(mProjection, mainCamera.viewRangeDg * degrees2radians, screenAspectRatio, nearClip, farClip);\n mat4x4_mul(mViewProjection, mProjection, mainCamera.lookAtMatrix);\n mViewProjection[1][3] = 0; \/\/keystone effect\n\n \/\/scan subjects\n int subjsN = gameSubjs.size();\n for (int subjN = 0; subjN < subjsN; subjN++) {\n GameSubj* pGS = gameSubjs.at(subjN);\n \/\/behavior - apply rotation speed\n pGS->moveSubj();\n \/\/prepare subject for rendering\n pGS->buildModelMatrix(pGS);\n \/\/build MVP matrix for given subject\n mat4x4_mul(mMVP, mViewProjection, pGS->ownModelMatrix);\n \/\/build Model-View (rotation) matrix for normals\n mat4x4_mul(mMV4x4, mainCamera.lookAtMatrix, (vec4*)pGS->ownCoords.getRotationMatrix());\n \/\/convert to 3x3 matrix\n float mMV3x3[3][3];\n for (int y = 0; y < 3; y++)\n for (int x = 0; x < 3; x++)\n mMV3x3[y][x] = mMV4x4[y][x];\n \/\/subj's distance from camera\n float cameraSpacePos[4];\n mat4x4_mul_vec4plus(cameraSpacePos, mainCamera.lookAtMatrix, pGS->ownCoords.pos, 1);\n float zDistance = abs(cameraSpacePos[2]);\n float cotangentA = 1.0f \/ tanf(degrees2radians * mainCamera.viewRangeDg \/ 2.0);\n float halfScreenVertSizeInUnits = zDistance \/ cotangentA;\n float sizeUnitPixelsSize = screenSize[1] \/ 2.0 \/ halfScreenVertSizeInUnits;\n \/\/render subject\n for (int i = 0; i < pGS->djTotalN; i++) {\n DrawJob* pDJ = DrawJob::drawJobs.at(pGS->djStartN + i);\n pDJ->execute((float*)mMVP, *mMV3x3, (float*)pGS->ownModelMatrix, dirToMainLight, mainCamera.ownCoords.pos, sizeUnitPixelsSize, NULL);\n }\n }\n \/\/synchronization\n while (1) {\n long long int currentMillis = getSystemMillis();\n long long int millisSinceLastFrame = currentMillis - lastFrameMillis;\n if (millisSinceLastFrame >= millisPerFrame) {\n lastFrameMillis = currentMillis;\n break;\n }\n }\n mySwapBuffers();\n return 1;\n}\nint TheGame::cleanUp() {\n int itemsN = gameSubjs.size();\n \/\/delete all UISubjs\n for (int i = 0; i < itemsN; i++) {\n GameSubj* pGS = gameSubjs.at(i);\n delete pGS;\n }\n gameSubjs.clear();\n \/\/clear all other classes\n Texture::cleanUp();\n Shader::cleanUp();\n DrawJob::cleanUp();\n return 1;\n}\nint TheGame::onScreenResize(int width, int height) {\n if (screenSize[0] == width && screenSize[1] == height)\n return 0;\n screenSize[0] = width;\n screenSize[1] = height;\n screenAspectRatio = (float)width \/ height;\n glViewport(0, 0, width, height);\n mainCamera.onScreenResize();\n mylog(" screen size %d x %d\\n", width, height);\n return 1;\n}\nGameSubj* TheGame::newGameSubj(std::string subjClass) {\n return (new GameSubj());\n}\nint TheGame::run() {\n getReady();\n while (!bExitGame) {\n drawFrame();\n }\n cleanUp();\n return 1;\n}\n\n<\/pre><\/div>\n\n\n<\/p>\n\n\n\n
- \u0414\u0440\u0443\u0433\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0443\u0442 – mainCamera.viewRangeDg = 20;<\/em> 30 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432 \u0431\u044b\u043b\u043e \u0448\u0438\u0440\u043e\u043a\u043e\u0432\u0430\u0442\u043e, \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0430, 20 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0430\u0442\u0443\u0440\u0430\u043b\u044c\u043d\u0435\u0435.<\/li>
- \u0418 \u043d\u043e\u0432\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f (\u0441\u0442\u0440\u043e\u043a\u0430 29).<\/li><\/ul>\n\n\n\n
\n\n\n\n7. \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n\n\n\n
\u0414\u043e:<\/strong><\/p>\n\n\n\n
<\/p>\n\n\n\n
<\/p>\n\n\n\n
(\u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438)<\/p>\n\n\n\n
\u041f\u043e\u0441\u043b\u0435:<\/strong><\/p>\n\n\n\n
<\/p>\n\n\n\n
<\/p>\n\n\n\n
\u0421 \u0437\u043e\u043b\u043e\u0447\u0435\u043d\u044b\u043c\u0438 \u0438 \u0442\u0438\u0441\u043d\u0435\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043d\u0442\u0430\u043c\u0438, \u0441\u043e \u0441\u0442\u044b\u043a\u043e\u043c \u043f\u0430\u0447\u043a\u0430-\u043a\u0440\u044b\u0448\u043a\u0430 \u043a\u0430\u043a normal map, \u0441 \u0437\u043e\u043b\u043e\u0442\u043e\u0439 \u043b\u0435\u043d\u0442\u043e\u0439\/\u043f\u043b\u043e\u043c\u0431\u043e\u0439\/\u043b\u0438\u043d\u0438\u0435\u0439.<\/p>\n\n\n\n
\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0435\u0449\u0435 \u0438 \u0441 \u043f\u043b\u0435\u043d\u043a\u043e\u0439 \u0438 \u0441 \u0430\u043a\u0446\u0438\u0437\u043d\u043e\u0439 \u043c\u0430\u0440\u043a\u043e\u0439.<\/p>\n\n\n\n