antispam-bee domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/ruwritingagame/public_html/wp-includes/functions.php on line 6131\u0417\u0434\u0435\u0441\u044c \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u043e\u043b\u043e\u0442\u0443\u044e \u043b\u0435\u043d\u0442\u043e\u0447\u043a\u0443 (\u043f\u043b\u043e\u043c\u0431\u0443). \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043b\u0438\u043d\u0438\u044f<\/strong>, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0447\u0435\u043a \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f:<\/p>\n\n\n\n 1. \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\a997modeler<\/strong>\\dt\\models\\misc\\marlboro01\\root01.txt<\/strong><\/em><\/p>\n\n\n <\/p>\n\n\n\n \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430:<\/p>\n\n\n\n \u0415\u0449\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u0445. \u0422\u0430\u043a\u0436\u0435, \u043f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u0441\u043b\u0443\u0447\u0430\u0435\u043c, \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f HalfVector<\/em>-\u0430 \u0438\u0437TheGame.cpp<\/em> \u0432 vertex shader. \u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b\u0438 1 HalfVector <\/em> \u0434\u043b\u044f \u0432\u0441\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u0430. \u0422\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u0435\u0435.<\/p>\n\n\n\n Phong vertex shader:<\/strong><\/p>\n\n\n\n 2. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\engine<\/strong>\\dt\\shaders\\phong_v<\/strong>.txt<\/em><\/p>\n\n\n <\/p>\n\n\n\n \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435:<\/p>\n\n\n\n Phong fragment shader:<\/strong><\/p>\n\n\n\n 3. 2. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\engine<\/strong>\\dt\\shaders\\phong_f<\/strong>.txt<\/em><\/p>\n\n\n <\/p>\n\n\n\n Normal map vertex shader:<\/strong><\/p>\n\n\n\n 4. 2. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\engine<\/strong>\\dt\\shaders\\nm_v<\/strong>.txt<\/em><\/p>\n\n\n <\/p>\n\n\n\n Normal map fragment shader:<\/strong><\/p>\n\n\n\n 5. 2. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043d\u0438\u0436\u0435\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/strong> \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e (overwrite) to\/as<\/p>\n\n\n\n C:\\CPP\\engine<\/strong>\\dt\\shaders\\nm_f<\/strong>.txt<\/em><\/p>\n\n\n <\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c – \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c.<\/p>\n\n\n\n 6. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c VS, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c\u00a0C:\\CPP\\a997modeler\\p_windows\\p_windows.sln<\/em>.<\/p>\n\n\n\n 7. \u0417\u0430\u043c\u0435\u043d\u0438\u043c Material.h<\/em> \u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n \u0412 \u043a\u043b\u0430\u0441\u0441\u0435 ModelLoader <\/strong>– \u043d\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b (\u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b).<\/p>\n\n\n\n 8. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.h<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 9. \u0417\u0430\u043c\u0435\u043d\u0438\u043c ModelLoader.cpp<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n <\/p>\n\n\n\n \u041a\u043e\u0433\u0434\u0430 \u043b\u0438\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430, \u043d\u0430\u0434\u043e \u0431 \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044f\u0445<\/em> \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0435. \u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437 \u043d\u0435\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c – \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u043d\u0438\u0438<\/em>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0435\u0440\u043f\u0435\u043d\u0434\u0438\u043a\u0443\u043b\u044f\u0440\u043d\u043e <\/strong>\u043b\u044e\u0431\u044b\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044f\u043c.<\/p>\n\n\n\n <\/p>\n\n\n\n \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u0445 \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/em> \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u0439<\/em>. \u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 ModelBuilder<\/strong>.<\/p>\n\n\n\n 10. \u0417\u0430\u043c\u0435\u043d\u0438\u043c\u00a0ModelBuilder1base.h <\/em>\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 11. \u0417\u0430\u043c\u0435\u043d\u0438\u043c\u00a0ModelBuilder1base.cpp <\/em>\u043a\u043e\u0434 \u043d\u0430: <\/p>\n\n\n <\/p>\n\n\n\n \u0412 \u043a\u043b\u0430\u0441\u0441\u0435 DrawJob <\/strong>\u043d\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f lineWidthIsImportant()<\/em> \u0438 \u043d\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 executeDrawJob()<\/em>:<\/p>\n\n\n\n 12. \u0417\u0430\u043c\u0435\u043d\u0438\u043c DrawJob.h<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 13. \u0417\u0430\u043c\u0435\u043d\u0438\u043c\u00a0DrawJob.cpp<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n \u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u043c. \u0423 \u043d\u0430\u0441 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435: uMM <\/em>(model matrix) \u0438 uCameraPosition<\/em> \u0432\u043c\u0435\u0441\u0442\u043e uHalfVector<\/em>. \u041f\u043b\u044e\u0441 \u043d\u043e\u0432\u044b\u0439 #define<\/em> – WIRE<\/strong><\/p>\n\n\n\n 14. \u0417\u0430\u043c\u0435\u043d\u0438\u043c Shader.h<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 15. \u0417\u0430\u043c\u0435\u043d\u0438\u043c Shader.cpp<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n \u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 – TheGame<\/em>. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0434\u0435\u0441\u044c \u0441\u0447\u0438\u0442\u0430\u0442\u044c uHalfVector<\/em>, \u043d\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0447\u0438\u0442\u0430\u0442\u044c sizeUnitPixelsSize<\/em> (\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442\u0430 \u0448\u0438\u0440\u0438\u043d\u044b \u043b\u0438\u043d\u0438\u0439 \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0440\u0438\u043d\u0433\u0435). \u041f\u043b\u044e\u0441 – \u043d\u043e\u0432\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 pDJ->execute(..)<\/em> <\/p>\n\n\n\n 16. \u0417\u0430\u043c\u0435\u043d\u0438\u043c\u00a0TheGame.cpp<\/em>\u00a0\u043a\u043e\u0434 \u043d\u0430:<\/p>\n\n\n <\/p>\n\n\n\n 17. \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 <\/p>\n\n\n\n \u0422\u0435\u043f\u0435\u0440\u044c – \u0441 \u0437\u043e\u043b\u043e\u0442\u043e\u0439 \u043b\u0435\u043d\u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n\n\n\n\n<texture_as="tx0" src="marlboro03small.png" ckey="#00ff00"\/>\n<mt_type="phong" uTex0_use="tx0" \/>\n<vs="box_tank" whl="53,83,21" ext=1 sectR=1 \/>\n<a="front v" xywh="2,1,323,495" mark="box_front"\/>\n<a="back v" xywh="2,1,323,495" mark="box_back"\/>\n<a="right all" xywh="327,1,128,495" mark="box_right"\/>\n<a="left all" xywh="457,1,128,495" mark="box_left"\/>\n<a="top" xywh="588,1,323,133"\/>\n<a="bottom" xywh="587,136,324,134"\/>\n\/\/golden prints\n<vs="box" whl="55.1,85.1,23.1" \/>\n<texture_as="whitenoise" src="\/dt\/common\/img\/whitenoise\/wn64_blur3.bmp"\/>\n<texture_as="gold" src="\/dt\/common\/img\/materials\/gold02roman.bmp" \/>\n<mt_type="mirror" uAlphaBlending uTex1mask_use="tx0" uTex1alphaChannelN=1 uTex0_use="whitenoise" uTex0translateChannelN=0 uTex3_use="gold" \/>\n\/\/side golden prints\n<a="right" xywh="342,12,101,10" whl="x,1.8,18.1" pxyz="x,39.8, -0.3" \/> \/\/Please do not litter\n<a="right" xywh="339,144,105,89" whl="x,15.35,18.9" pxyz="x,10.3,-0.12" \/> \/\/For special offers...\n<a="left" xywh="475,15,95,48" whl="x,8.4,17" pxyz="x,36, 0.3" \/> \/\/Underage sale...\n\/\/front prints\n<group>\n\t\/\/bottom golden print "20 class a..."\n\t<a="front" xywh="20,498,289,13" whl="47.5,2,x" pxyz="1,-36,x" \/>\n\t\/\/blazon\/emblem\n\t<mt_type="mirror" uAlphaBlending uTex2nm_use="tx0" uTex0_use="whitenoise" uTex0translateChannelN=0 uTex3_use="gold" \/>\n\t<a="front" xywh2nm="589,415,128,94" whl="20.7,16,x" pxyz="0.3,6.1,x" \/> \/\/emblem\n\t\/\/"Marlboro\n\t<mt_type="phong" uAlphaBlending uTex2nm_use="tx0" uColor="#1E211E" \/>\n\t<a="front" xywh2nm="590,275,301,136" whl="49.2,23.3,x" pxyz="0.21,-18,x" \/> \/\/marlboro\n<\/group> \n<clone ay=180 \/>\n\/\/joint (slit) between the pack and the lid\n<group>\n\t<mt_adjust uTex2nm_use="tx0" >\n\t\t<a2mesh wh="50,1" xywh2nm="582,497,1,4" all markedAs="box_right" onThe="right" py=24.6 az=31 \/>\n\t\t<a2mesh wh="50,1" xywh2nm="582,497,1,4" all markedAs="box_left" onThe="left" py=24.6 az=-31 \/>\n\t\t<a2mesh wh="53,1" xywh2nm="582,497,1,4" all markedAs="box_front" py=17.8 \/>\n\t\t<a2mesh wh="6 ,1" xywh2nm="582,497,1,4" all markedAs="box_back" onThe="back" py=31.5 px=23.5 \/>\n\t\t<a2mesh wh="6 ,1" xywh2nm="582,497,1,4" all markedAs="box_back" onThe="back" py=31.5 px=-23.5 \/>\n\t<\/mt_adjust> \n<\/group sizeD="0.1,0,0.1"> \n\/\/sealing ribbon\n<mt_type="wire" lineWidth=1.5 uColor="130,90,0" >\n<line>\n\t<p pxyz="-27.6,16.5 ,0" \/>\n\t<p dz=10.5 \/> \/\/left side half\n\t<p dxyz="1.1,0,1.1" \/> \/\/front left rib\n\t<p dx=53 \/> \/\/front side\n\t<p dxyz="1.1,0,-1.1" \/> \/\/front right rib\n\t<p dz=-21 \/> \/\/right side\n\t<p dxyz="-1.1,0,-1.1" \/> \/\/back right rib\n\t<p dx=-53 \/> \/\/back side\n\t<p dxyz="-1.1,0,1.1" \/> \/\/back left rib\n\t<p dz=16 \/> \/\/left half\n\t<p dxyz="-1,0,5" \/> \/\/ribbon "tail"\n\t<p dz=1 \/>\n<\/line >\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n\/\/#version 320 es\nprecision lowp float;\nuniform mat4 uMVP; \/\/ transform matrix (Model-View-Projection)\nuniform mat3 uMV3x3; \/\/ Model-View matrix (for calculating normals into eye space)\n\nin vec3 aPos; \/\/ position attribute (x,y,z)\n#if defined(USE_NORMALS)\n\tin vec3 aNormal; \/\/ normal attribute (x,y,z)\n\tout vec3 vNormal; \/\/ varying normal (to pass to fragment shader)\n#endif\n#if defined(USE_TUV0)\n\tin vec2 aTuv; \/\/attribute TUV (texture coordinates)\n\tout vec2 vTuv; \/\/varying TUV (pass to fragment shader)\n#endif\n#if defined(MIRROR)\n\tout vec2 vTuvMirror; \/\/varying TUV (pass to fragment shader)\n#endif\n#if defined(PHONG)\n\tuniform mat4 uMM; \/\/ Model matrix (for vHalfVector for glares)\n\tuniform vec3 uVectorToLight;\n\tuniform vec3 uCameraPosition; \/\/for calculating half vector for glares\n\tuniform float uSpecularIntencity; \/\/for calculating half vector for glares\n\tout vec3 vHalfVector;\n#endif\n\nvoid main(void) { \n\tgl_Position = uMVP * vec4(aPos, 1.0);\n#if defined(USE_NORMALS)\t\n\t\/\/ Transform the normal's orientation into eye space. \n\tvNormal = uMV3x3 * aNormal;\t\n#endif\n#if defined(USE_TUV0)\n\tvTuv = aTuv;\n#endif\n#if defined(MIRROR)\n\tvTuvMirror[0] = (gl_Position[0]\/gl_Position[3]*0.1+vNormal[0]*0.4)+0.5;\n\tvTuvMirror[1] = -(gl_Position[1]\/gl_Position[3]*0.1+vNormal[1]*0.4)+0.5;\n#endif\n#if defined(PHONG)\n\tif(uSpecularIntencity > 0.0){ \/\/for glares\n\t\tvec4 vxPos = uMM * vec4(aPos, 1.0); \/\/vertex position\n\t\tvec3 dirToCamera = normalize(uCameraPosition - vec3(vxPos));\n\t\tvHalfVector = normalize(dirToCamera + uVectorToLight);\n\t}\n#endif\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n\/\/#version 320 es\nprecision lowp float;\nout vec4 FragColor; \/\/output pixel color\nuniform float uAlphaFactor; \/\/for semi-transparency\nuniform int uAlphaBlending; \/\/for semi-transparency\n\n#if defined(USE_NORMALS)\n\tin vec3 vNormal; \/\/normal passed from rasterizer\n#endif\n#if defined(USE_TEX0)\n\tuniform sampler2D uTex0; \/\/texture id\n\tuniform sampler2D uTex3; \/\/translate texture id\n\tuniform int uTex0translateChannelN;\n#else\n\tuniform vec4 uColor;\n#endif\n#if defined(USE_TUV0)\n\tin vec2 vTuv; \/\/varying TUV (passed from vertex shader)\n#endif\n#if defined(MIRROR)\n\tin vec2 vTuvMirror; \/\/varying TUV (passed from vertex shader)\n#endif\n#if defined(OVERMASK)\n\tuniform sampler2D uTex1mask; \/\/texture id\n\tuniform int uTex1alphaChannelN;\n\tuniform int uTex1alphaNegative;\n#endif\n\n#if defined(PHONG)\n\tuniform float uAmbient;\n\tuniform float uSpecularIntencity;\n\tuniform float uSpecularMinDot;\n\tuniform float uSpecularPowerOf;\n\n\tuniform vec3 uVectorToLight;\n\tin vec3 vHalfVector;\n#endif\n\nvoid main(void) {\n\n\tvec4 outColor;\n\tfloat alpha = 1.0;\n#if defined(OVERMASK)\n\toutColor = texture(uTex1mask, vTuv);\n\talpha = outColor[uTex1alphaChannelN];\n\tif(uTex1alphaNegative > 0)\n\t\talpha = 1.0 - alpha;\n\tif(alpha < 0.5){\n\t\tif(uAlphaBlending > 0){\n\t\t\tif(alpha == 0.0){\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\telse{ \/\/no AlphaBlending\n\t\t\tdiscard;\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n#if defined(USE_TEX0)\n\t#if defined(MIRROR)\n\t\toutColor = texture(uTex0, vTuvMirror);\n\t#else\n\t\toutColor = texture(uTex0, vTuv);\n\t#endif\n\tif(uTex0translateChannelN >= 0){ \/\/translate channel\n\t\tvec2 tuv3;\n\t\ttuv3[0] = outColor[uTex0translateChannelN];\n\t\ttuv3[1] = 0.0;\n\t\toutColor = texture(uTex3, tuv3);\n\t}\n\tFragColor = outColor;\n#else\n\tFragColor = uColor;\n#endif\n\tif(FragColor.a != 1.0){\n\t\talpha *= FragColor.a;\n\t\tif(alpha < 0.5){\n\t\t\tif(uAlphaBlending > 0){\n\t\t\t\tif(alpha == 0.0){\n\t\t\t\t\tdiscard;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{ \/\/no AlphaBlending\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n#if defined(USE_NORMALS)\n\tvec3 vNormalNormal = normalize(vNormal);\n#endif\n\n#if defined(PHONG)\n\tif(uAmbient<1.0){\n\t\t\/\/ Calculate the dot product of the light vector and vertex normal. If the normal and light vector are\n\t\t\/\/ pointing in the same direction then it will get max illumination.\n\t\tfloat dotProduct = dot(vNormalNormal, uVectorToLight);\n#if defined(WIRE)\n\t\tif(dotProduct < 0.0)\n\t\t\tdotProduct = -dotProduct;\n\t\tdotProduct = 1.0 - dotProduct;\n#endif\t\t\n\t\t\/\/ count ambient component\n\t\tdotProduct += uAmbient;\n\t\tif(dotProduct < uAmbient)\n\t\t\tdotProduct = uAmbient;\n\n\t\t\/\/ Multiply the color by the lightIntencity illumination level to get final output color.\n\t\tFragColor *= dotProduct;\n\t}\n\tif(uSpecularIntencity>0.0){\n\t\t\/\/specular light\n\t\t\/\/ INTENSITY OF THE SPECULAR LIGHT\n\t\t\/\/ DOT PRODUCT OF NORMAL VECTOR AND THE HALF VECTOR TO THE POWER OF THE SPECULAR HARDNESS\n\t\tvec3 vNormalHalfVector = normalize(vHalfVector);\n\t\tfloat dotProduct = dot(vNormalNormal, vNormalHalfVector);\n#if defined(WIRE)\n\t\tif(dotProduct < 0.0)\n\t\t\tdotProduct = -dotProduct;\n\t\tdotProduct = 1.0 - dotProduct;\n#endif\t\t\n\t\tif(dotProduct>uSpecularMinDot){\n\t\t\tfloat specularIntencity = pow(dotProduct, uSpecularPowerOf) * uSpecularIntencity;\t\t\n\t\t\tif(specularIntencity > uSpecularIntencity)\n\t\t\t\tspecularIntencity = uSpecularIntencity;\n\t\t\tFragColor += specularIntencity;\n\t\t}\n\t}\n#endif\n\tif(uAlphaFactor != 1.0)\n\t\talpha *= uAlphaFactor;\t\n\tFragColor.a = alpha;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n\/\/#version 320 es\nprecision lowp float;\nuniform mat4 uMVP; \/\/ transform matrix (Model-View-Projection)\nuniform mat3 uMV3x3; \/\/ Model-View matrix (for calculating normals into eye space)\nuniform mat4 uMM; \/\/ Model matrix (for vHalfVector for glares)\nin vec3 aPos; \/\/ position attribute (x,y,z)\nin vec3 aNormal; \/\/ normal attribute (x,y,z)\n\/\/normal map\nin vec3 aTangent;\nin vec3 aBinormal;\nin vec2 aTuv2; \/\/attribute TUV2 (texture coordinates)\nout vec2 vTuv2; \/\/varying TUV2 (pass to fragment shader)\nuniform vec3 uVectorToLight;\nuniform vec3 uCameraPosition; \/\/for calculating half vector for glares\nuniform float uSpecularIntencity; \/\/for calculating half vector for glares\n\nout vec3 tbnVectorToLight;\nout vec3 tbnHalfVector;\n#if defined(MIRROR)\n\tout vec2 vScreenPosition01;\n\tout mat3 inversedTBN;\n#endif\n#if defined(USE_TUV0)\n\tin vec2 aTuv; \/\/attribute TUV (texture coordinates)\n\tout vec2 vTuv; \/\/varying TUV (pass to fragment shader)\n#endif\n\nvoid main(void) { \n\tgl_Position = uMVP * vec4(aPos, 1.0);\n#if defined(USE_TUV0)\n\tvTuv = aTuv;\n#endif\n\n\tvTuv2 = aTuv2;\n\n\t\/\/ Transform the normal's orientation into eye space. \n\tvec3 N = uMV3x3 * aNormal;\n\tvec3 T = uMV3x3 * aTangent;\n\tvec3 B = uMV3x3 * aBinormal;\n\t\/\/build TBN matrix\n\tmat3 TBN = mat3(\n\t\t\tT[0],B[0],N[0],\n\t\t\tT[1],B[1],N[1],\n\t\t\tT[2],B[2],N[2]\n\t\t\t);\n\ttbnVectorToLight = TBN * uVectorToLight;\n\tif(uSpecularIntencity > 0.0){ \/\/for glares\n\t\tvec4 vxPos = uMM * vec4(aPos, 1.0); \/\/vertex position\n\t\tvec3 dirToCamera = normalize(uCameraPosition - vec3(vxPos));\n\t\tvec3 vHalfVector = normalize(dirToCamera + uVectorToLight);\n\t\ttbnHalfVector = TBN * vHalfVector;\n\t}\n#if defined(MIRROR)\n\tvScreenPosition01[0] = (gl_Position[0]\/gl_Position[3])*0.1;\n\tvScreenPosition01[1] = -(gl_Position[1]\/gl_Position[3])*0.1;\n\tinversedTBN = inverse(TBN);\n#endif\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n\/\/#version 320 es\nprecision lowp float;\nout vec4 FragColor; \/\/output pixel color\nuniform float uAlphaFactor; \/\/for semi-transparency\nuniform int uAlphaBlending; \/\/for semi-transparency\n\nin vec2 vTuv2;\nuniform sampler2D uTex2nm;\nin vec3 tbnVectorToLight;\nin vec3 tbnHalfVector;\n\n#if defined(USE_TEX0)\n\tuniform sampler2D uTex0; \/\/texture id\n\tuniform sampler2D uTex3; \/\/translate texture id\n\tuniform int uTex0translateChannelN;\n#else\n\tuniform vec4 uColor;\n#endif\n#if defined(USE_TUV0)\n\tin vec2 vTuv; \/\/varying TUV (passed from vertex shader)\n#endif\n#if defined(OVERMASK)\n\tuniform sampler2D uTex1mask; \/\/texture id\n\tuniform int uTex1alphaChannelN;\n\tuniform int uTex1alphaNegative;\n#endif\n#if defined(MIRROR)\n\tin vec2 vScreenPosition01;\n\tin mat3 inversedTBN;\n#endif\nuniform float uAmbient;\nuniform float uSpecularIntencity;\nuniform float uSpecularMinDot;\nuniform float uSpecularPowerOf;\n\nvoid main(void) {\n\tvec4 tbnNormal4 = texture(uTex2nm, vTuv2);\n\tfloat alpha = tbnNormal4.a;\n\n\tif(alpha < 0.5){\n\t\tif(uAlphaBlending > 0){\n\t\t\tif(alpha == 0.0){\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\telse{ \/\/no AlphaBlending\n\t\t\tdiscard;\n\t\t\treturn;\n\t\t}\n\t}\n\t\/\/black?\n\tif(tbnNormal4.b < 0.3){\n\t\tFragColor = vec4(0.0,0.0,0.0,alpha);\n\t\treturn;\n\t}\t\n\tvec4 outColor;\n#if defined(OVERMASK)\n\toutColor = texture(uTex1mask, vTuv);\n\tfloat alpha2 = outColor[uTex1alphaChannelN];\n\tif(uTex1alphaNegative > 0)\n\t\talpha2 = 1.0 - alpha2;\n\tif(alpha2 < 1.0){\n\t\talpha *= alpha2;\n\t\tif(alpha < 0.5){\n\t\t\tif(uAlphaBlending > 0){\n\t\t\t\tif(alpha == 0.0){\n\t\t\t\t\tdiscard;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{ \/\/no AlphaBlending\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n#endif\n\tvec3 vNormalNormal = normalize(vec3(tbnNormal4) * 2.0 - 1.0);\n\n#if defined(USE_TEX0)\n\t#if defined(MIRROR)\n\t\tvec3 inversedNormal = normalize(inversedTBN * vNormalNormal);\n\t\tvec2 vTuvMirror;\n\t\tvTuvMirror[0] = (vScreenPosition01[0]+inversedNormal[0]*0.4)+0.5;\n\t\tvTuvMirror[1] = -(vScreenPosition01[1]+inversedNormal[1]*0.4)+0.5;\n\t\toutColor = texture(uTex0, vTuvMirror);\n\t#else\n\t\toutColor = texture(uTex0, vTuv);\n\t#endif\n\tif(uTex0translateChannelN >= 0){ \/\/translate channel\n\t\tvec2 tuv3;\n\t\ttuv3[0] = outColor[uTex0translateChannelN];\n\t\ttuv3[1] = 0.0;\n\t\toutColor = texture(uTex3, tuv3);\n\t}\n\tFragColor = outColor;\n#else\n\tFragColor = uColor;\n#endif\n\tif(FragColor.a != 1.0){\n\t\talpha *= FragColor.a;\n\t\tif(alpha < 0.5){\n\t\t\tif(uAlphaBlending > 0){\n\t\t\t\tif(alpha == 0.0){\n\t\t\t\t\tdiscard;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{ \/\/no AlphaBlending\n\t\t\t\tdiscard;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tif(uAmbient<1.0){\n\t\t \/\/ Calculate the dot product of the light vector and vertex normal. If the normal and light vector are\n\t\t \/\/ pointing in the same direction then it will get max illumination.\n\t\t float dotProduct = dot(vNormalNormal, normalize(tbnVectorToLight));\n#if defined(WIRE)\n\t\tif(dotProduct < 0.0)\n\t\t\tdotProduct = -dotProduct;\n\t\tdotProduct = 1.0 - dotProduct;\n#endif\t\t\n\t\t \/\/ count ambient component\n\t\t dotProduct += uAmbient;\n\t\t if(dotProduct < uAmbient)\n\t\t\tdotProduct = uAmbient;\n\n\t\t \/\/ Multiply the color by the lightIntencity illumination level to get final output color.\n\t\t FragColor *= dotProduct;\n\t}\n\tif(uSpecularIntencity>0.0){\n\t\t\/\/specular light\n\t\t\/\/ INTENSITY OF THE SPECULAR LIGHT\n\t\t\/\/ DOT PRODUCT OF NORMAL VECTOR AND THE HALF VECTOR TO THE POWER OF THE SPECULAR HARDNESS\n\t\tfloat dotProduct = dot(vNormalNormal, normalize(tbnHalfVector));\n#if defined(WIRE)\n\t\tif(dotProduct < 0.0)\n\t\t\tdotProduct = -dotProduct;\n\t\tdotProduct = 1.0 - dotProduct;\n#endif\t\t\n\t\tif(dotProduct>uSpecularMinDot){\n\t\t\tfloat specularIntencity = pow(dotProduct, uSpecularPowerOf) * uSpecularIntencity;\t\t\n\t\t\tif(specularIntencity > uSpecularIntencity)\n\t\t\t\tspecularIntencity = uSpecularIntencity;\n\t\t\tFragColor += specularIntencity;\n\t\t}\n\t}\n\tif(uAlphaFactor != 1.0)\n\t\talpha *= uAlphaFactor;\t\n\tFragColor.a = alpha;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\nWindows<\/h2>\n\n\n\n
\n\n\n\n\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\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
\n\n\n\n\n#pragma once\n#include "XMLparser.h"\n#include "ModelBuilder.h"\n#include "GroupTransform.h"\n#include "MaterialAdjust.h"\n\nclass ModelLoader : public XMLparser\n{\npublic:\n\tModelBuilder* pModelBuilder = NULL;\n\tbool ownModelBuilder = false;\n\tstd::vector<GameSubj*>* pSubjsVector = NULL;\n\tMaterialAdjust* pMaterialAdjust = NULL;\n\tint lineStartsAt = -1;\npublic:\n\tModelLoader(std::vector<GameSubj*>* pSubjsVector0, int subjN, ModelBuilder* pMB, std::string filePath) : XMLparser(filePath) {\n\t\tpSubjsVector = pSubjsVector0;\n\t\tif (pMB != NULL) {\n\t\t\townModelBuilder = false;\n\t\t\tpModelBuilder = pMB;\n\t\t}\n\t\telse {\n\t\t\townModelBuilder = true;\n\t\t\tpModelBuilder = new ModelBuilder();\n\t\t\tpModelBuilder->lockGroup(pModelBuilder);\n\t\t}\n\t\tpModelBuilder->useSubjN(pModelBuilder,subjN);\n\t};\n\tvirtual ~ModelLoader() {\n\t\tif (!ownModelBuilder)\n\t\t\treturn;\n\t\tpModelBuilder->buildDrawJobs(pModelBuilder, *pSubjsVector);\n\t\tdelete pModelBuilder;\n\t};\n\tstatic int processTag_a(ModelLoader* pML); \/\/apply\n\tstatic int setValueFromIntHashMap(int* pInt, std::map<std::string, int> intHashMap, std::string varName, std::string tagStr);\n\tstatic int setTexture(ModelLoader* pML, int* pInt, std::string txName);\n\tstatic int setMaterialTextures(ModelLoader* pML, Material* pMT);\n\tstatic int fillProps_vs(VirtualShape* pVS, std::string tagStr); \/\/virtual shape\n\tstatic int fillProps_mt(Material* pMT, std::string tagStr, ModelLoader* pML); \/\/Material\n\tstatic int fillProps_gt(GroupTransform* pGS, ModelBuilder* pMB, std::string tagStr);\n\tvirtual int processTag() { return processTag(this); };\n\tstatic int processTag(ModelLoader* pML);\n\tstatic int loadModel(std::vector<GameSubj*>* pSubjsVector0, std::string sourceFile, std::string subjClass);\n\tstatic int processTag_clone(ModelLoader* pML);\n\tstatic int addMark(char* marks, std::string newMark);\n\tstatic int processTag_do(ModelLoader* pML);\n\tstatic int processTag_a2mesh(ModelLoader* pML);\n};\n\n<\/pre><\/div>\n\n\n
\n\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\tsetIntBoolValue(&pMT->uAlphaBlending, "uAlphaBlending", tagStr);\n\tsetFloatValue(&pMT->uAlphaFactor, "uAlphaFactor", tagStr);\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\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\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\t\/\/move\/rotate\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
\n\n\n\n
<\/p>\n\n\n\n\n#pragma once\n#include <string>\n#include <vector>\n#include "Vertex01.h"\n#include "Triangle01.h"\n#include "VirtualShape.h"\n#include "Group01.h"\n#include "Material.h"\n#include "GameSubj.h"\n#include <map>\n\nclass ModelBuilder1base\n{\npublic:\n\tstd::vector<Vertex01*> vertices;\n\tstd::vector<Triangle01*> triangles;\n\tstd::vector<int> subjNumbersList;\n\tint usingSubjN = -1;\n\n\tstd::vector<Group01*> groupsStack;\n\tGroup01* pCurrentGroup = NULL;\n\tGroup01* pLastClosedGroup = NULL;\n\t\n\tstd::vector<VirtualShape*> vShapesStack;\n\tVirtualShape* pCurrentVShape = NULL;\n\n\tstd::vector<Material*> materialsList;\n\tint usingMaterialN = -1;\n\tstd::vector<int> materialsStack;\n\n\tstd::map<std::string, int> texturesHashMap;\npublic:\n\tvirtual ~ModelBuilder1base();\n\tstatic int useSubjN(ModelBuilder1base* pMB, int subjN);\n\tstatic int getMaterialN(ModelBuilder1base* pMB, Material* pMT);\n\tstatic void lockGroup(ModelBuilder1base* pMB);\n\tstatic void releaseGroup(ModelBuilder1base* pMB);\n\tstatic int addVertex(ModelBuilder1base* pMB, float kx, float ky, float kz, float nx, float ny, float nz);\n\tstatic int add2triangles(ModelBuilder1base* pMB, int nNW, int nNE, int nSW, int nSE, int n);\n\tstatic int addTriangle(ModelBuilder1base* pMB, int n0, int n1, int n2);\n\tstatic int buildDrawJobs(ModelBuilder1base* pMB, std::vector<GameSubj*> gameSubjs);\n\tstatic int rearrangeArraysForDrawJob(ModelBuilder1base* pMB, std::vector<Vertex01*> allVertices, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\n\tstatic int buildSingleDrawJob(Material* pMT, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\n\tstatic int moveGroupDg(ModelBuilder1base* pMB, float aX, float aY, float aZ, float kX, float kY, float kZ);\n\tstatic int calculateTangentSpace(std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles);\n\tstatic int finalizeLine(std::vector<Vertex01*> verts, int lineStartsAt=0, int lineEndsAt=0);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "ModelBuilder1base.h"\n#include "platform.h"\n#include "utils.h"\n#include "DrawJob.h"\n#include "Shader.h"\n\nextern float degrees2radians;\n\nModelBuilder1base::~ModelBuilder1base() {\n\treleaseGroup(this);\n\n\t\/\/clear all vectors\n\tint itemsN = vertices.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete vertices.at(i);\n\tvertices.clear();\n\n\titemsN = triangles.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete triangles.at(i);\n\ttriangles.clear();\n\n\titemsN = vShapesStack.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete vShapesStack.at(i);\n\tvShapesStack.clear();\n\n\titemsN = groupsStack.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete groupsStack.at(i);\n\tgroupsStack.clear();\n\tif (pCurrentGroup != NULL)\n\t\tdelete pCurrentGroup;\n\tif (pLastClosedGroup != NULL)\n\t\tdelete pLastClosedGroup;\n\n\titemsN = materialsList.size();\n\tfor (int i = 0; i < itemsN; i++)\n\t\tdelete materialsList.at(i);\n\tmaterialsList.clear();\n\n\tsubjNumbersList.clear();\n}\nint ModelBuilder1base::useSubjN(ModelBuilder1base* pMB, int subjN) {\n\tpMB->usingSubjN = subjN;\n\tint itemsN = pMB->subjNumbersList.size();\n\tbool newN = true;\n\tif (itemsN > 0)\n\t\tfor (int i = 0; i < itemsN; i++)\n\t\t\tif (pMB->subjNumbersList.at(i) == subjN) {\n\t\t\t\tnewN = false;\n\t\t\t\tbreak;\n\t\t\t}\n\tif (newN)\n\t\tpMB->subjNumbersList.push_back(subjN);\n\treturn subjN;\n}\nint ModelBuilder1base::getMaterialN(ModelBuilder1base* pMB, Material* pMT) {\n\tint itemsN = pMB->materialsList.size();\n\tif (itemsN > 0)\n\t\tfor (int i = 0; i < itemsN; i++)\n\t\t\tif (memcmp(pMB->materialsList.at(i), pMT, sizeof(Material)) == 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\/\/if here - add new material to the list\n\tMaterial* pMTnew = new Material(*pMT);\n\tpMB->materialsList.push_back(pMTnew);\n\treturn itemsN;\n}\nint ModelBuilder1base::add2triangles(ModelBuilder1base* pMB, int nNW, int nNE, int nSW, int nSE, int n) {\n\t\/\/indexes: NorthWest, NorthEast, SouthWest,SouthEast\n\tif (n % 2 == 0) { \/\/even number\n\t\taddTriangle(pMB, nNW, nSW, nNE);\n\t\taddTriangle(pMB, nNE, nSW, nSE);\n\t}\n\telse { \/\/odd number\n\t\taddTriangle(pMB, nNW, nSE, nNE);\n\t\taddTriangle(pMB, nNW, nSW, nSE);\n\t}\n\treturn pMB->triangles.size() - 1;\n}\nint ModelBuilder1base::addTriangle(ModelBuilder1base* pMB, int i0, int i1, int i2) {\n\tTriangle01* pTR = new Triangle01();\n\tpMB->triangles.push_back(pTR);\n\tpTR->idx[0] = i0;\n\tpTR->idx[1] = i1;\n\tpTR->idx[2] = i2;\n\tpTR->subjN = pMB->usingSubjN;\n\tpTR->materialN = pMB->usingMaterialN;\n\t\/\/mark\n\tif (pMB->pCurrentGroup != NULL)\n\t\tif (strcmp(pMB->pCurrentGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pTR->marks, 124, pMB->pCurrentGroup->marks);\n\treturn pMB->triangles.size() - 1;\n}\nint ModelBuilder1base::addVertex(ModelBuilder1base* pMB, float kx, float ky, float kz, float nx, float ny, float nz) {\n\tVertex01* pVX = new Vertex01();\n\tpMB->vertices.push_back(pVX);\n\tpVX->aPos[0] = kx;\n\tpVX->aPos[1] = ky;\n\tpVX->aPos[2] = kz;\n\t\/\/normal\n\tpVX->aNormal[0] = nx;\n\tpVX->aNormal[1] = ny;\n\tpVX->aNormal[2] = nz;\n\tpVX->subjN = pMB->usingSubjN;\n\tpVX->materialN = pMB->usingMaterialN;\n\t\/\/mark\n\tif (pMB->pCurrentGroup != NULL)\n\t\tif (strcmp(pMB->pCurrentGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pVX->marks, 124, pMB->pCurrentGroup->marks);\n\n\treturn pMB->vertices.size() - 1;\n}\nint ModelBuilder1base::buildDrawJobs(ModelBuilder1base* pMB, std::vector<GameSubj*> gameSubjs) {\n\tint totalSubjsN = pMB->subjNumbersList.size();\n\tif (totalSubjsN < 1) {\n\t\tpMB->subjNumbersList.push_back(-1);\n\t\ttotalSubjsN = 1;\n\t}\n\tint totalMaterialsN = pMB->materialsList.size();\n\tif (totalSubjsN < 2 && totalMaterialsN < 2) {\n\t\t\/\/simple single DrawJob\n\t\tMaterial* pMT = pMB->materialsList.at(0);\n\t\tGameSubj* pGS = NULL;\n\t\tint gsN = pMB->subjNumbersList.at(0);\n\t\tif (gsN >= 0)\n\t\t\tpGS = gameSubjs.at(gsN);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djStartN = DrawJob::drawJobs.size();\n\t\tbuildSingleDrawJob(pMT, pMB->vertices, pMB->triangles);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\t\treturn 1;\n\t}\n\tint totalVertsN = pMB->vertices.size();\n\tint totalTrianglesN = pMB->triangles.size();\n\t\/\/clear flags\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = pMB->vertices.at(vN);\n\t\tpVX->flag = 0;\n\t}\n\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\tTriangle01* pTR = pMB->triangles.at(tN);\n\t\tpTR->flag = 0;\n\t}\n\tint addedDJs = 0;\n\tfor (int sN = 0; sN < totalSubjsN; sN++) {\n\t\tGameSubj* pGS = NULL;\n\t\tint gsN = pMB->subjNumbersList.at(sN);\n\t\tif (gsN >= 0)\n\t\t\tpGS = gameSubjs.at(gsN);\n\t\tif (pGS != NULL)\n\t\t\tpGS->djStartN = DrawJob::drawJobs.size();\n\t\tfor (int mtN = 0; mtN < totalMaterialsN; mtN++) {\n\t\t\tMaterial* pMT = pMB->materialsList.at(mtN);\n\t\t\tstd::vector<Vertex01*> useVertices;\n\t\t\tstd::vector<Triangle01*> useTriangles;\n\t\t\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\t\t\tVertex01* pVX = pMB->vertices.at(vN);\n\t\t\t\tif (pVX->flag != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pVX->subjN != gsN)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pVX->materialN != mtN)\n\t\t\t\t\tcontinue;\n\t\t\t\t\/\/if here - make a copy\n\t\t\t\tVertex01* pVX2 = new Vertex01(*pVX);\n\t\t\t\tuseVertices.push_back(pVX2);\n\t\t\t\tpVX2->altN = vN;\n\t\t\t\tpVX->flag = 1;\n\t\t\t\tif (pVX->endOfSequence > 0) {\n\t\t\t\t\t\/\/rearrangeArraysForDrawJob(pMB, pMB->vertices, useVertices, useTriangles);\n\t\t\t\t\tbuildSingleDrawJob(pMT, useVertices, useTriangles);\n\t\t\t\t\taddedDJs++;\n\t\t\t\t\t\/\/clear and proceed to next sequence\n\t\t\t\t\tint useVerticesN = useVertices.size();\n\t\t\t\t\tfor (int i = 0; i < useVerticesN; i++)\n\t\t\t\t\t\tdelete useVertices.at(i);\n\t\t\t\t\tuseVertices.clear();\n\t\t\t\t}\n\t\t\t}\n\t\t\tint useVerticesN = useVertices.size();\n\t\t\tif (useVerticesN < 1)\n\t\t\t\tcontinue; \/\/to next material\n\t\t\t\/\/pick triangles\n\t\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\t\tTriangle01* pTR = pMB->triangles.at(tN);\n\t\t\t\tif (pTR->flag != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pTR->subjN != gsN)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (pTR->materialN != mtN)\n\t\t\t\t\tcontinue;\n\t\t\t\t\/\/if here - make a copy\n\t\t\t\tTriangle01* pTR2 = new Triangle01(*pTR);\n\t\t\t\tuseTriangles.push_back(pTR2);\n\t\t\t\tpTR->flag = 1;\n\t\t\t}\n\t\t\trearrangeArraysForDrawJob(pMB, pMB->vertices, useVertices, useTriangles);\n\t\t\tbuildSingleDrawJob(pMT, useVertices, useTriangles);\n\t\t\taddedDJs++;\n\t\t\t\/\/clear all for next material\n\t\t\tfor (int i = 0; i < useVerticesN; i++)\n\t\t\t\tdelete useVertices.at(i);\n\t\t\tuseVertices.clear();\n\t\t\tint useTrianglesN = useTriangles.size();\n\t\t\tfor (int i = 0; i < useTrianglesN; i++)\n\t\t\t\tdelete useTriangles.at(i);\n\t\t\tuseTriangles.clear();\n\t\t}\n\t\tif (pGS != NULL)\n\t\t\tpGS->djTotalN = DrawJob::drawJobs.size() - pGS->djStartN;\n\t}\n\treturn addedDJs;\n}\nint ModelBuilder1base::buildSingleDrawJob(Material* pMT, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalVertsN = useVertices.size();\n\tif (totalVertsN < 1)\n\t\treturn 0;\n\tif (DrawJob::lineWidthIsImportant(pMT->primitiveType))\n\t\tif(strcmp(pMT->shaderType,"wire")==0)\n\t\t\tfinalizeLine(useVertices);\n\tif (pMT->uTex2nm >= 0)\n\t\tcalculateTangentSpace(useVertices, useTriangles);\n\tpMT->pickShaderNumber();\n\tDrawJob* pDJ = new DrawJob();\n\t\/\/copy material to DJ\n\tmemcpy(&pDJ->mt, pMT, sizeof(Material));\n\t\/\/calculate VBO element size (stride) and variables offsets in VBO\n\tint VBOid = DrawJob::newBufferId();\n\tint stride = 0;\n\tpDJ->setDesirableOffsets(&stride, pDJ->mt.shaderN, VBOid);\n\t\/\/create an array for VBO\n\tint bufferSize = totalVertsN * stride;\n\tfloat* vertsBuffer = new float[bufferSize];\n\t\/\/fill vertsBuffer\n\tShader* pSh = Shader::shaders.at(pDJ->mt.shaderN);\n\tint floatSize = sizeof(float);\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = useVertices.at(vN);\n\t\tint idx = vN * stride \/ floatSize;\n\t\t\/\/pick data from vertex and move to the buffer\n\t\tmemcpy(&vertsBuffer[idx + pDJ->aPos.offset \/ floatSize], pVX->aPos, 3 * floatSize);\n\t\tif (pSh->l_aNormal >= 0) \/\/normal\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aNormal.offset \/ floatSize], pVX->aNormal, 3 * floatSize);\n\t\tif (pSh->l_aTuv >= 0) \/\/attribute TUV (texture coordinates)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTuv.offset \/ floatSize], pVX->aTuv, 2 * floatSize);\n\t\tif (pSh->l_aTuv2 >= 0) \/\/attribute TUV2 (normal maps)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTuv2.offset \/ floatSize], pVX->aTuv2, 2 * floatSize);\n\t\tif (pSh->l_aTangent >= 0)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aTangent.offset \/ floatSize], pVX->aTangent, 3 * floatSize);\n\t\tif (pSh->l_aBinormal >= 0)\n\t\t\tmemcpy(&vertsBuffer[idx + pDJ->aBinormal.offset \/ floatSize], pVX->aBinormal, 3 * floatSize);\n\t}\n\t\/\/buffer is ready, create VBO\n\tglBindBuffer(GL_ARRAY_BUFFER, VBOid);\n\tglBufferData(GL_ARRAY_BUFFER, bufferSize * floatSize, vertsBuffer, GL_STATIC_DRAW);\n\tdelete[] vertsBuffer;\n\tpDJ->pointsN = totalVertsN;\n\n\tint totalTrianglesN = useTriangles.size();\n\tif (totalTrianglesN > 0) {\n\t\t\/\/create EBO\n\t\tint totalIndexesN = totalTrianglesN * 3;\n\t\t\/\/create buffer\n\t\tGLushort* indexBuffer = new GLushort[totalIndexesN];\n\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\tTriangle01* pTR = useTriangles[tN];\n\t\t\tint idx = tN * 3;\n\t\t\tindexBuffer[idx] = (GLushort)pTR->idx[0];\n\t\t\tindexBuffer[idx + 1] = (GLushort)pTR->idx[1];\n\t\t\tindexBuffer[idx + 2] = (GLushort)pTR->idx[2];\n\t\t}\n\t\t\/\/buffer is ready, create IBO\n\t\tpDJ->glEBOid = DrawJob::newBufferId();\n\t\tglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pDJ->glEBOid);\n\t\tglBufferData(GL_ELEMENT_ARRAY_BUFFER, totalIndexesN * sizeof(GLushort), indexBuffer, GL_STATIC_DRAW);\n\t\tdelete[] indexBuffer;\n\t\tpDJ->pointsN = totalIndexesN;\n\t}\n\t\/\/create and fill vertex attributes array (VAO)\n\tpDJ->buildVAO();\n\treturn 1;\n}\n\nint ModelBuilder1base::rearrangeArraysForDrawJob(ModelBuilder1base* pMB, std::vector<Vertex01*> allVertices, std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalTrianglesN = useTriangles.size();\n\tif (totalTrianglesN < 1)\n\t\treturn 0;\n\tint totalVerticesN = useVertices.size();\n\t\/\/save new vertices order in original vertices array\n\t\/\/since triangles indices refer to original vertices order\n\tfor (int i = 0; i < totalVerticesN; i++) {\n\t\tVertex01* pVX1 = useVertices.at(i);\n\t\tVertex01* pVX0 = allVertices.at(pVX1->altN);\n\t\tpVX0->altN = i;\n\t}\n\t\/\/replace triangle original indices by new numbers saved in original vertices altN\n\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\tTriangle01* pTR = useTriangles.at(tN);\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tVertex01* pVX0 = allVertices.at(pTR->idx[i]);\n\t\t\tpTR->idx[i] = pVX0->altN;\n\t\t}\n\t}\n\treturn 1;\n}\n\nint ModelBuilder1base::moveGroupDg(ModelBuilder1base* pMB, float aX, float aY, float aZ, float kX, float kY, float kZ) {\n\t\/\/moves and rotates vertex group\n\t\/\/rotation angles are set in degrees\n\tmat4x4 transformMatrix = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };\n\tmat4x4_translate(transformMatrix, kX, kY, kZ);\n\t\/\/rotation order: Z-X-Y\n\tif (aY != 0) mat4x4_rotate_Y(transformMatrix, transformMatrix, degrees2radians * aY);\n\tif (aX != 0) mat4x4_rotate_X(transformMatrix, transformMatrix, degrees2radians * aX);\n\tif (aZ != 0) mat4x4_rotate_Z(transformMatrix, transformMatrix, degrees2radians * aZ);\n\n\tint vertsN = pMB->vertices.size();\n\tfor (int i = pMB->pCurrentGroup->fromVertexN; i < vertsN; i++) {\n\t\tVertex01* pVX = pMB->vertices.at(i);\n\t\tmat4x4_mul_vec4plus(pVX->aPos, transformMatrix, pVX->aPos, 1);\n\t\tmat4x4_mul_vec4plus(pVX->aNormal, transformMatrix, pVX->aNormal, 0);\n\t}\n\treturn 1;\n}\n\nint ModelBuilder1base::calculateTangentSpace(std::vector<Vertex01*> useVertices, std::vector<Triangle01*> useTriangles) {\n\tint totalVertsN = useVertices.size();\n\tif (totalVertsN < 1)\n\t\treturn 0;\n\tint totalTrianglesN = useTriangles.size();\n\t\/\/assuming that GL_TRIANGLES\n\t\/\/clear flags\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pV = useVertices.at(vN);\n\t\tpV->flag = 0;\n\t}\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pVX = useVertices.at(vN);\n\t\tif (pVX->flag != 0)\n\t\t\tcontinue;\n\t\tTriangle01* pT = NULL;\n\t\tfor (int tN = 0; tN < totalTrianglesN; tN++) {\n\t\t\tpT = useTriangles.at(tN);\n\t\t\tbool haveTriangle = false;\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t\tif (pT->idx[i] == vN) {\n\t\t\t\t\thaveTriangle = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\tif (haveTriangle)\n\t\t\t\tbreak;\n\t\t}\n\t\tVertex01* pV[3];\n\t\tfor (int i = 0; i < 3; i++)\n\t\t\tpV[i] = useVertices.at(pT->idx[i]);\n\n\t\tfloat dPos1[3];\n\t\tfloat dPos2[3];\n\t\tfloat dUV1[2];\n\t\tfloat dUV2[2];\n\t\tfor (int i = 0; i < 3; i++) {\n\t\t\tdPos1[i] = pV[1]->aPos[i] - pV[0]->aPos[i];\n\t\t\tdPos2[i] = pV[2]->aPos[i] - pV[0]->aPos[i];\n\t\t}\n\t\tfor (int i = 0; i < 2; i++) {\n\t\t\tdUV1[i] = pV[1]->aTuv2[i] - pV[0]->aTuv2[i];\n\t\t\tdUV2[i] = pV[2]->aTuv2[i] - pV[0]->aTuv2[i];\n\t\t}\n\n\t\tfloat tangent[3];\n\t\tfloat binormal[3];\n\t\tfloat divider = dUV1[0] * dUV2[1] - dUV1[1] * dUV2[0];\n\t\tif (divider == 0) {\n\t\t\tv3set(tangent, 1, 0, 0);\n\t\t\tv3set(binormal, 0, -1, 0);\n\t\t}\n\t\telse {\n\t\t\tfloat r = 1.0f \/ divider;\n\t\t\tfor (int i = 0; i < 3; i++) {\n\t\t\t\ttangent[i] = (dPos1[i] * dUV2[1] - dPos2[i] * dUV1[1]) * r;\n\t\t\t\tbinormal[i] = -(dPos2[i] * dUV1[0] - dPos1[i] * dUV2[0]) * r;\n\t\t\t}\n\t\t\tvec3_norm(tangent, tangent);\n\t\t\tvec3_norm(binormal, binormal);\n\t\t}\n\t\t\/\/add to all 3 vertices\n\t\tfor (int n = 0; n < 3; n++) {\n\t\t\tif (pV[n]->flag > 0)\n\t\t\t\tcontinue;\n\t\t\tv3copy(pV[n]->aTangent, tangent);\n\t\t\tv3copy(pV[n]->aBinormal, binormal);\n\t\t\tpV[n]->flag = 1;\n\t\t}\n\t}\n\t\/\/normalize tangent and binormal around normal\n\tfor (int vN = 0; vN < totalVertsN; vN++) {\n\t\tVertex01* pV = useVertices.at(vN);\n\t\tfloat v3out[3];\n\t\t\/\/tangent\n\t\tvec3_mul_cross(v3out, pV->aNormal, pV->aBinormal);\n\t\tif (v3dotProduct(pV->aTangent, v3out) < 0)\n\t\t\tv3inverse(v3out);\n\t\tv3copy(pV->aTangent, v3out);\n\t\t\/\/binormal\n\t\tvec3_mul_cross(v3out, pV->aNormal, pV->aTangent);\n\t\tif (v3dotProduct(pV->aBinormal, v3out) < 0)\n\t\t\tv3inverse(v3out);\n\t\tv3copy(pV->aBinormal, v3out);\n\t}\n\treturn 1;\n}\nvoid ModelBuilder1base::lockGroup(ModelBuilder1base* pMB) {\n\tGroup01* pPrevGroup = pMB->pCurrentGroup;\n\tif (pMB->pCurrentGroup != NULL)\n\t\tpMB->groupsStack.push_back(pMB->pCurrentGroup);\n\tpMB->pCurrentGroup = new Group01();\n\tpMB->pCurrentGroup->fromVertexN = pMB->vertices.size();\n\tpMB->pCurrentGroup->fromTriangleN = pMB->triangles.size();\n\t\/\/marks\n\tif(pPrevGroup != NULL)\n\t\tif (strcmp(pPrevGroup->marks, "") != 0)\n\t\t\tmyStrcpy_s(pMB->pCurrentGroup->marks, 124, pPrevGroup->marks);\n}\nvoid ModelBuilder1base::releaseGroup(ModelBuilder1base* pMB) {\n\tif (pMB->pLastClosedGroup != NULL)\n\t\tdelete pMB->pLastClosedGroup;\n\tpMB->pLastClosedGroup = pMB->pCurrentGroup;\n\n\tif (pMB->groupsStack.size() > 0) {\n\t\tpMB->pCurrentGroup = pMB->groupsStack.back();\n\t\tpMB->groupsStack.pop_back();\n\t}\n\telse\n\t\tpMB->pCurrentGroup = NULL;\n}\nint ModelBuilder1base::finalizeLine(std::vector<Vertex01*> verts, int lineStartsAt, int lineEndsAt) {\n\tif (lineEndsAt <= 0)\n\t\tlineEndsAt = verts.size() - 1;\n\tVertex01* pV0 = verts.at(lineStartsAt);\n\tVertex01* pV2 = verts.at(lineEndsAt);\n\tbool closedLine = false;\n\tif (v3match(pV0->aPos, pV2->aPos))\n\t\tclosedLine = true;\n\tfor (int vN = lineStartsAt; vN <= lineEndsAt; vN++) {\n\t\tVertex01* pV = verts.at(vN);\n\t\t\/\/prev point\n\t\tif (vN == lineStartsAt) {\n\t\t\t\/\/first point\n\t\t\tif (closedLine)\n\t\t\t\tpV0 = verts.at(lineEndsAt);\n\t\t\telse\n\t\t\t\tpV0 = NULL;\n\t\t}\n\t\telse\n\t\t\tpV0 = verts.at(vN - 1);\n\t\t\/\/next point\n\t\tif (vN == lineEndsAt) {\n\t\t\t\/\/last point\n\t\t\tif (closedLine)\n\t\t\t\tpV2 = verts.at(lineStartsAt);\n\t\t\telse\n\t\t\t\tpV2 = NULL;\n\t\t}\n\t\telse\n\t\t\tpV2 = verts.at(vN + 1);\n\t\t\/\/distances to neighbor points\n\t\tfloat distFromPrev = 0;\n\t\tfloat dirFromPrev[3] = { 0,0,0 };\n\t\tif (pV0 != NULL) {\n\t\t\tdistFromPrev = v3lengthFromTo(pV0->aPos, pV->aPos);\n\t\t\tv3dirFromTo(dirFromPrev, pV0->aPos, pV->aPos);\n\t\t}\n\t\tfloat distToNext = 0;\n\t\tfloat dirToNext[3] = { 0,0,0 };\n\t\tif (pV2 != NULL) {\n\t\t\tdistToNext = v3lengthFromTo(pV->aPos, pV2->aPos);\n\t\t\tv3dirFromTo(dirToNext, pV->aPos, pV2->aPos);\n\t\t}\n\t\tfloat distTotal = distFromPrev + distToNext;\n\t\tfloat kPrev = distFromPrev \/ distTotal;\n\t\tfloat kNext = distToNext \/ distTotal;\n\t\tif (kPrev > kNext * 3)\n\t\t\tv3copy(pV->aNormal, dirFromPrev);\n\t\telse if (kNext > kPrev * 3)\n\t\t\tv3copy(pV->aNormal, dirToNext);\n\t\telse\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t\tpV->aNormal[i] = kPrev * dirFromPrev[i] + kNext * dirToNext[i];\n\t\tvec3_norm(pV->aNormal, pV->aNormal);\n\t}\n\treturn 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#pragma once\n#include "Material.h"\n#include <vector>\n\nstruct AttribRef \/\/attribute reference\/description\n{\n\tunsigned int glVBOid = 0; \/\/buffer object id\n\tint offset = 0; \/\/variable's offset inside of VBO's element\n\tint stride = 0; \/\/Buffer's element size in bytes\n};\n\nclass DrawJob\n{\npublic:\n\tMaterial mt;\n\tint pointsN = 0; \/\/N of points to draw\n\tunsigned int glVAOid = 0; \/\/will hold data stream attributes mapping\/positions\n\tunsigned int glEBOid = 0; \/\/Element Buffer Object (vertex indices)\n\n\t\/\/common attributes\n\tAttribRef aPos;\n\tAttribRef aNormal;\n\tAttribRef aTuv;\n\tAttribRef aTuv2; \/\/for normal map\n\tAttribRef aTangent; \/\/for normal map\n\tAttribRef aBinormal; \/\/for normal map\n\n\t\/\/static arrays (vectors) of all loaded DrawJobs, VBO ids\n\tstatic std::vector<DrawJob*> drawJobs;\n\tstatic std::vector<unsigned int> buffersIds;\npublic:\n\tDrawJob();\n\tvirtual ~DrawJob(); \/\/destructor\n\tstatic int cleanUp();\n\tstatic int newBufferId();\n\tint buildVAO() { return buildVAOforShader(this, mt.shaderN); };\n\tstatic int buildVAOforShader(DrawJob* pDJ, int shaderN);\n\tstatic int attachAttribute(int varLocationInShader, int attributeSizeInFloats, AttribRef* pAttribRef);\n\n\tvirtual int setDesirableOffsets(int* pStride, int shaderN, int VBOid) { return setDesirableOffsetsForSingleVBO(this, pStride, shaderN, VBOid); };\n\tstatic int setDesirableOffsetsForSingleVBO(DrawJob* pDJ, int* pStride, int shaderN, int VBOid);\n\n\tint execute(float* uMVP, float* uMV, float* uMM, float* uVectorToLight, float* uCameraPosition, float sizeUnitPixelsSize = 0, Material* pMt=NULL) { return executeDrawJob(this, uMVP, uMV, uMM, uVectorToLight, uCameraPosition, sizeUnitPixelsSize, pMt); };\n\tstatic int executeDrawJob(DrawJob* pDJ, float* uMVP, float* uMV, float* uMM, float* uVectorToLight, float* uCameraPosition, float sizeUnitPixelsSize = 0, Material* pMt=NULL);\n\tstatic bool lineWidthIsImportant(int primitiveType);\n};\n\n<\/pre><\/div>\n\n\n
\n\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 (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\tif (lineWidthIsImportant(pMt->primitiveType)) {\n\t\tfloat lw = sizeUnitPixelsSize * pMt->lineWidth;\n\t\tglLineWidth(lw);\n\t}\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
\n\n\n\n\n#pragma once\n#include "platform.h"\n#include <string>\n#include <vector>\n\nclass Shader\n{\npublic:\n \/\/Shader program's individual descriptor:\n unsigned int GLid = -1; \/\/ GL shader id\n char shaderType[20] = "";\n \/\/common variables, "l_" for "location"\n \/\/attributes\n int l_aPos; \/\/attribute position (3D coordinates)\n int l_aTuv; \/\/attribute TUV (texture coordinates)\n int l_aTuv2; \/\/attribute TUV (texture coordinates for normal map)\n int l_aNormal; \/\/attribute normal (3D vector)\n int l_aTangent; \/\/for normal map\n int l_aBinormal; \/\/for normal map\n \/\/uniforms\n int l_uMVP; \/\/ transform matrix (Model-View-Projection)\n int l_uMV3x3; \/\/ Model-View matrix for normals\n int l_uMM; \/\/ Model matrix for HalfVector\n int l_uVectorToLight; \/\/required for light\n int l_uCameraPosition; \/\/required for specular light\n \/\/material's properties\n int l_uColor;\n int l_uTex0; \/\/texture id\n int l_uTex1mask; \/\/transparency map\n int l_uTex2nm; \/\/normal map\n int l_uTex3; \/\/texture id\n int l_uTex1alphaChannelN; \/\/alpha channel for mask\n int l_uTex1alphaNegative; \/\/alpha channel negative\n int l_uTex0translateChannelN; \/\/translate tex0 to tex3 by channelN.\n int l_uAlphaFactor; \/\/for semi-transparency\n int l_uAlphaBlending; \/\/for semi-transparency\n \/\/light:\n int l_uAmbient; \/\/ambient light\n \/\/specular light parameters\n int l_uSpecularIntencity;\n int l_uSpecularMinDot;\n int l_uSpecularPowerOf;\n \/\/end of descriptor\n\n \/\/static array (vector) of all loaded shaders\n static std::vector<Shader*> shaders;\n\npublic:\n static int loadShaders();\n static int cleanUp();\n static unsigned int getGLid(int shN) { return shaders.at(shN)->GLid; };\n static int shaderErrorCheck(int shaderId, std::string ref);\n static int programErrorCheck(int programId, std::string ref);\n static int fillLocations(Shader* pSh);\n\n static int buildShaderObjectFromFiles(std::string filePathVertexS, std::string filePathFragmentS);\n static int linkShaderProgramFromFiles(const char* filePathVertexS, const char* filePathFragmentS);\n\tstatic int compileShaderFromFile(const char* filePath, GLenum shaderType);\n\n static int buildShaderObjectWithDefines(std::string shaderType, std::string definesString, char* sourceVertex, char* sourceFragment);\n static int linkShaderProgramWithDefines(std::string definesString, char* sourceVertex, char* sourceFragment);\n static int compileShaderWithDefines(std::string definesString, char* shaderSource, GLenum shaderType);\n\n static int loadShadersGroup(std::string shaderType, std::string optionsString, char* sourceVertex, char* sourceFragment);\n};\n\n<\/pre><\/div>\n\n\n
\n\n\n\n\n#include "Shader.h"\n#include "platform.h"\n#include "utils.h"\n#include "FileLoader.h"\n\nextern std::string filesRoot;\n\n\/\/static array (vector) of all loaded shaders\nstd::vector<Shader*> Shader::shaders;\n\nint Shader::loadShaders() {\n FileLoader* pFLvertex = new FileLoader("\/dt\/shaders\/phong_v.txt");\n FileLoader* pFLfragment = new FileLoader("\/dt\/shaders\/phong_f.txt");\n loadShadersGroup("flat", "FLAT; COLOR | TEXTURE; NONE | OVERMASK", pFLvertex->pData, pFLfragment->pData);\n loadShadersGroup("phong", "PHONG; COLOR | TEXTURE; NONE | OVERMASK", pFLvertex->pData, pFLfragment->pData);\n loadShadersGroup("mirror", "PHONG;MIRROR; NONE | OVERMASK", pFLvertex->pData, pFLfragment->pData);\n loadShadersGroup("wire", "WIRE;PHONG; COLOR | TEXTURE", pFLvertex->pData, pFLfragment->pData);\n delete pFLvertex;\n delete pFLfragment;\n \/\/Normal Maps\n pFLvertex = new FileLoader("\/dt\/shaders\/nm_v.txt");\n pFLfragment = new FileLoader("\/dt\/shaders\/nm_f.txt");\n loadShadersGroup("phong", "COLOR | TEXTURE; NONE | OVERMASK", pFLvertex->pData, pFLfragment->pData);\n loadShadersGroup("mirror", "MIRROR; NONE | OVERMASK", pFLvertex->pData, pFLfragment->pData);\n delete pFLvertex;\n delete pFLfragment;\n return 1;\n}\n\nint Shader::buildShaderObjectFromFiles(std::string filePathVertexS, std::string filePathFragmentS) {\n \/\/create shader object\n Shader* pSh = new Shader();\n shaders.push_back(pSh);\n pSh->GLid = linkShaderProgramFromFiles((filesRoot + filePathVertexS).c_str(), (filesRoot + filePathFragmentS).c_str());\n \/\/common variables. If not presented, = -1;\n fillLocations(pSh);\n\n return (shaders.size() - 1);\n}\n\nint Shader::fillLocations(Shader* pSh) {\n \/\/common variables. If not presented, = -1;\n \/\/attributes\n pSh->l_aPos = glGetAttribLocation(pSh->GLid, "aPos"); \/\/attribute position (3D coordinates)\n pSh->l_aNormal = glGetAttribLocation(pSh->GLid, "aNormal"); \/\/attribute normal (3D vector)\n pSh->l_aTangent = glGetAttribLocation(pSh->GLid, "aTangent"); \/\/for normal map\n pSh->l_aBinormal = glGetAttribLocation(pSh->GLid, "aBinormal"); \/\/for normal map\n pSh->l_aTuv = glGetAttribLocation(pSh->GLid, "aTuv"); \/\/attribute TUV (texture coordinates)\n pSh->l_aTuv2 = glGetAttribLocation(pSh->GLid, "aTuv2"); \/\/attribute TUV (texture coordinates)\n \/\/uniforms\n pSh->l_uMVP = glGetUniformLocation(pSh->GLid, "uMVP"); \/\/ transform matrix (Model-View-Projection)\n pSh->l_uMV3x3 = glGetUniformLocation(pSh->GLid, "uMV3x3"); \/\/ Model-View matrix for normals\n pSh->l_uMM = glGetUniformLocation(pSh->GLid, "uMM"); \/\/ Model matrix for HalfVector\n pSh->l_uVectorToLight = glGetUniformLocation(pSh->GLid, "uVectorToLight"); \/\/ \n pSh->l_uCameraPosition = glGetUniformLocation(pSh->GLid, "uCameraPosition"); \/\/ required for specular light\n \/\/material's properties\n pSh->l_uColor = glGetUniformLocation(pSh->GLid, "uColor");\n pSh->l_uTex0 = glGetUniformLocation(pSh->GLid, "uTex0"); \/\/texture id\n pSh->l_uTex1mask = glGetUniformLocation(pSh->GLid, "uTex1mask"); \/\/texture id\n pSh->l_uTex2nm = glGetUniformLocation(pSh->GLid, "uTex2nm"); \/\/texture id\n pSh->l_uTex3 = glGetUniformLocation(pSh->GLid, "uTex3"); \/\/texture id\n pSh->l_uTex1alphaChannelN = glGetUniformLocation(pSh->GLid, "uTex1alphaChannelN");\n pSh->l_uTex1alphaNegative = glGetUniformLocation(pSh->GLid, "uTex1alphaNegative");\n pSh->l_uTex0translateChannelN = glGetUniformLocation(pSh->GLid, "uTex0translateChannelN");\n pSh->l_uAlphaFactor = glGetUniformLocation(pSh->GLid, "uAlphaFactor"); \/\/ for semi-transparency\n pSh->l_uAlphaBlending = glGetUniformLocation(pSh->GLid, "uAlphaBlending"); \/\/ for semi-transparency\n pSh->l_uAmbient = glGetUniformLocation(pSh->GLid, "uAmbient"); \/\/ ambient light\n pSh->l_uSpecularIntencity = glGetUniformLocation(pSh->GLid, "uSpecularIntencity"); \/\/ \n pSh->l_uSpecularMinDot = glGetUniformLocation(pSh->GLid, "uSpecularMinDot"); \/\/ \n pSh->l_uSpecularPowerOf = glGetUniformLocation(pSh->GLid, "uSpecularPowerOf"); \/\/ \n return 1;\n}\nint Shader::cleanUp() {\n int shadersN = shaders.size();\n if (shadersN < 1)\n return -1;\n glUseProgram(0);\n for (int i = 0; i < shadersN; i++) {\n Shader* pSh = shaders.at(i);\n glDeleteProgram(pSh->GLid);\n delete pSh;\n }\n shaders.clear();\n return 1;\n}\n\nGLchar infoLog[1024];\nint logLength;\nint Shader::shaderErrorCheck(int shaderId, std::string ref) {\n \/\/use after glCompileShader()\n if (checkGLerrors(ref) > 0)\n return -1;\n glGetShaderInfoLog(shaderId, 1024, &logLength, infoLog);\n if (logLength == 0)\n return 0;\n mylog("%s shader infoLog:\\n%s\\n", ref.c_str(), infoLog);\n return -1;\n}\nint Shader::programErrorCheck(int programId, std::string ref) {\n \/\/use after glLinkProgram()\n if (checkGLerrors(ref) > 0)\n return -1;\n glGetProgramInfoLog(programId, 1024, &logLength, infoLog);\n if (logLength == 0)\n return 0;\n mylog("%s program infoLog:\\n%s\\n", ref.c_str(), infoLog);\n return -1;\n}\n\nint Shader::compileShaderFromFile(const char* filePath, GLenum shaderType) {\n int shaderId = glCreateShader(shaderType);\n FILE* pFile;\n myFopen_s(&pFile, filePath, "rt");\n if (pFile != NULL)\n {\n \/\/ obtain file size:\n fseek(pFile, 0, SEEK_END);\n int fSize = ftell(pFile);\n rewind(pFile);\n \/\/ size obtained, create buffer\n char* shaderSource = new char[fSize + 1];\n fSize = fread(shaderSource, 1, fSize, pFile);\n shaderSource[fSize] = 0;\n fclose(pFile);\n \/\/ source code loaded, compile\n glShaderSource(shaderId, 1, (const GLchar**)&shaderSource, NULL);\n \/\/myglErrorCheck("glShaderSource");\n glCompileShader(shaderId);\n if (shaderErrorCheck(shaderId, "glCompileShader") < 0)\n return -1;\n delete[] shaderSource;\n }\n else {\n mylog("ERROR loading %s\\n", filePath);\n return -1;\n }\n return shaderId;\n}\nint Shader::linkShaderProgramFromFiles(const char* filePathVertexS, const char* filePathFragmentS) {\n int vertexShaderId = compileShaderFromFile(filePathVertexS, GL_VERTEX_SHADER);\n int fragmentShaderId = compileShaderFromFile(filePathFragmentS, GL_FRAGMENT_SHADER);\n int programId = glCreateProgram();\n glAttachShader(programId, vertexShaderId);\n glAttachShader(programId, fragmentShaderId);\n glLinkProgram(programId);\n if (programErrorCheck(programId, "glLinkProgram") < 0)\n return -1;\n \/\/don't need shaders any longer - detach and delete them\n glDetachShader(programId, vertexShaderId);\n glDetachShader(programId, fragmentShaderId);\n glDeleteShader(vertexShaderId);\n glDeleteShader(fragmentShaderId);\n return programId;\n}\n\nint Shader::buildShaderObjectWithDefines(std::string shaderType, std::string definesString, char* sourceVertex, char* sourceFragment) {\n \/\/create shader object\n Shader* pSh = new Shader();\n shaders.push_back(pSh);\n myStrcpy_s(pSh->shaderType, 20, shaderType.c_str());\n\n pSh->GLid = linkShaderProgramWithDefines(definesString, sourceVertex, sourceFragment);\n \/\/common variables. If not presented, = -1;\n fillLocations(pSh);\n\n return (shaders.size() - 1);\n}\n\nint Shader::linkShaderProgramWithDefines(std::string definesString00, char* sourceVertex, char* sourceFragment) {\n \/\/build extended definesString\n bool bUSE_NORMALS = false;\n bool bUSE_TEX0 = false;\n bool bUSE_TUV0 = false;\n if (definesString00.find(" PHONG\\n") != std::string::npos)\n bUSE_NORMALS = true;\n if (definesString00.find(" TEXTURE\\n") != std::string::npos) {\n bUSE_TEX0 = true;\n bUSE_TUV0 = true;\n }\n if (definesString00.find(" MIRROR\\n") != std::string::npos) {\n bUSE_NORMALS = true;\n bUSE_TEX0 = true;\n }\n if (definesString00.find(" OVERMASK\\n") != std::string::npos) {\n bUSE_TUV0 = true;\n }\n std::string definesString;\n definesString.assign("#version 320 es\\n");\n definesString.append(definesString00);\n if (bUSE_NORMALS)\n definesString.append("#define USE_NORMALS\\n");\n if (bUSE_TEX0)\n definesString.append("#define USE_TEX0\\n");\n if (bUSE_TUV0)\n definesString.append("#define USE_TUV0\\n");\n\n int vertexShaderId = compileShaderWithDefines(definesString, sourceVertex, GL_VERTEX_SHADER);\n int fragmentShaderId = compileShaderWithDefines(definesString, sourceFragment, GL_FRAGMENT_SHADER);\n\n int programId = glCreateProgram();\n glAttachShader(programId, vertexShaderId);\n glAttachShader(programId, fragmentShaderId);\n glLinkProgram(programId);\n if (programErrorCheck(programId, "glLinkProgram") < 0)\n return -1;\n \/\/don't need shaders any longer - detach and delete them\n glDetachShader(programId, vertexShaderId);\n glDetachShader(programId, fragmentShaderId);\n glDeleteShader(vertexShaderId);\n glDeleteShader(fragmentShaderId);\n \/\/mylog("linking program\\n%s\\n", definesString.c_str());\n return programId;\n}\nint Shader::compileShaderWithDefines(std::string definesString, char* shaderSource, GLenum shaderType) {\n int shaderId = glCreateShader(shaderType);\n if (definesString.empty())\n glShaderSource(shaderId, 1, (const GLchar**)&shaderSource, NULL);\n else { \/\/2 strings\n const char* sourceStrings[2];\n sourceStrings[0] = definesString.c_str();\n sourceStrings[1] = shaderSource;\n \/\/ source code loaded, compile\n glShaderSource(shaderId, 2, (const GLchar**)sourceStrings, NULL);\n }\n \/\/myglErrorCheck("glShaderSource");\n glCompileShader(shaderId);\n if (shaderErrorCheck(shaderId, "glCompileShader") < 0) {\n mylog("ERROR in compileShader,\\n%s\\n%s\\n", definesString.c_str(), shaderSource);\n return -1;\n }\n return shaderId;\n}\n\nint Shader::loadShadersGroup(std::string shaderType, std::string optionsString, char* sourceVertex, char* sourceFragment) {\n struct Terms {\n std::vector<std::string> terms;\n int totalN = 0;\n int currentN = 0;\n };\n std::vector<Terms*> terms;\n std::vector<std::string> termGroups = splitString(optionsString, ";");\n int groupsN = termGroups.size();\n for (int groupN = 0; groupN < groupsN; groupN++) {\n Terms* pTerms = new Terms();\n terms.push_back(pTerms);\n pTerms->terms = splitString(termGroups.at(groupN), "|");\n pTerms->totalN = pTerms->terms.size();\n }\n while (1) {\n std::string definesString = "";\n for (int groupN = 0; groupN < groupsN; groupN++) {\n Terms* pTerms = terms.at(groupN);\n std::string term = pTerms->terms.at(pTerms->currentN);\n if (term.compare("NONE") != 0) {\n definesString.append("#define ");\n definesString.append(term);\n definesString.append("\\n");\n }\n }\n int shaderObjN = buildShaderObjectWithDefines(shaderType, definesString, sourceVertex, sourceFragment);\n \/\/go to next terms combo\n bool noMoreOptions = false;\n for (int groupN = groupsN - 1; groupN >= 0; groupN--) {\n Terms* pTerms = terms.at(groupN);\n if (pTerms->currentN < pTerms->totalN - 1) {\n pTerms->currentN++;\n break;\n }\n else { \/\/ the level exhausted\n pTerms->currentN = 0;\n \/\/proceed to upper level\n if (groupN == 0) {\n noMoreOptions = true;\n break;\n }\n }\n }\n if (noMoreOptions)\n break;\n }\n return 1;\n}\n\n<\/pre><\/div>\n\n\n
\n\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(0, 2, 0);\n \/\/pGS->ownCoords.setDegrees(0, -90, 0);\n\n \/\/===== set up camera\n mainCamera.ownCoords.setDegrees(15, 180, 0); \/\/set camera angles\/orientation\n mainCamera.viewRangeDg = 30;\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}\n\nint TheGame::drawFrame() {\n myPollEvents(); \n\n \/\/glClearColor(0.0, 0.0, 0.5, 1.0);\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 - 50;\n float farClip = mainCamera.focusDistance + 50;\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}\nint TheGame::run() {\n getReady();\n while (!bExitGame) {\n drawFrame();\n }\n cleanUp();\n return 1;\n}\nGameSubj* TheGame::newGameSubj(std::string subjClass) {\n return (new GameSubj());\n}\n\n<\/pre><\/div>\n\n\n
\n\n\n\n
<\/p>\n\n\n\n