Revisão | 13 (tree) |
---|---|
Hora | 2016-06-12 23:36:46 |
Autor | mocchi_2012 |
・シェーダで傾きが大きいところを暗くする処理を追加
・グループ毎に色を付けるモードの追加
@@ -14,7 +14,12 @@ | ||
14 | 14 | RenderingMode *rendering_mode; |
15 | 15 | |
16 | 16 | public: |
17 | - bool *show_flag; | |
17 | + struct Group{ | |
18 | + ON_String name; | |
19 | + bool showflag; | |
20 | + ON_Color group_color; | |
21 | + bool force_groupcolor; | |
22 | + }*group; | |
18 | 23 | irr::video::SMaterial Material, WMaterial; |
19 | 24 | bool IsSelectable; |
20 | 25 | bool Selected; |
@@ -27,7 +32,7 @@ | ||
27 | 32 | irr::core::array<irr::u32> WIndices; |
28 | 33 | |
29 | 34 | CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, irr::core::vector3df upv, |
30 | - int wire_mode, RenderingMode *rendering_mode, bool *showflag); | |
35 | + int wire_mode, RenderingMode *rendering_mode, Group *group, irr::video::E_MATERIAL_TYPE mat_type); | |
31 | 36 | // CONObjSceneNode(const ONX_Model *model, const ON_Brep *brep, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, irr::core::vector3df upv, int wire_mode, RenderingMode *rendering_mode); |
32 | 37 | |
33 | 38 | virtual void OnRegisterSceneNode(); |
@@ -40,9 +40,11 @@ | ||
40 | 40 | // : scene::ISceneNode(parent, mgr, id) |
41 | 41 | // { |
42 | 42 | CONObjSceneNode::CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, ISceneNode* parent, ISceneManager* mgr, s32 id, irr::core::vector3df upv, |
43 | - int wire_mode_, RenderingMode *rendering_mode_, bool *show_flag_) | |
44 | - : ISceneNode(parent, mgr, id), wire_mode(wire_mode_), rendering_mode(rendering_mode_), show_flag(show_flag_) { | |
43 | + int wire_mode_, RenderingMode *rendering_mode_, Group *group_, video::E_MATERIAL_TYPE mat_type) | |
44 | + : ISceneNode(parent, mgr, id), wire_mode(wire_mode_), rendering_mode(rendering_mode_), group(group_){ | |
45 | 45 | |
46 | + setMaterialType(mat_type); | |
47 | + | |
46 | 48 | // ONModel = model; |
47 | 49 | ONAttribute = attr; |
48 | 50 | IsSelectable = true; |
@@ -160,7 +162,6 @@ | ||
160 | 162 | WIndices.push_back(iter->first.Y); |
161 | 163 | } |
162 | 164 | } |
163 | - | |
164 | 165 | } |
165 | 166 | |
166 | 167 | #if 0 |
@@ -334,15 +335,20 @@ | ||
334 | 335 | */ |
335 | 336 | void CONObjSceneNode::render() { |
336 | 337 | if (Indices.size() == 0 || Vertices.size() == 0) return; |
337 | - if (!(*show_flag)) return; | |
338 | + if (!group->showflag) return; | |
338 | 339 | |
339 | 340 | // ON_Color col = Selected ? ON_Color(255, 128, 0, 255) : GetColorFromAttr(ONAttribute, ONModel->m_layer_table); |
340 | - ON_Color col = Selected ? ON_Color(255, 128, 0, 255) : ONAttribute.m_color; | |
341 | + ON_Color col; | |
342 | + if (Selected) col = ON_Color(255, 128, 0, 255); | |
343 | + else if (group->force_groupcolor) col = group->group_color; | |
344 | + else col = ONAttribute.m_color; | |
341 | 345 | |
342 | 346 | Material.SpecularColor = Selected ? irr::video::SColor(255-col.Alpha(), 0, 0, 0) : irr::video::SColor(255-col.Alpha(), 128, 128, 128); |
347 | + Material.SpecularColor = Selected ? irr::video::SColor(255-col.Alpha(), 0, 0, 0) : irr::video::SColor(255-col.Alpha(), 64, 64, 64); | |
343 | 348 | Material.AmbientColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()*3/4, 64 + col.Green()*3/4, 64 + col.Blue()*3/4); |
344 | 349 | Material.DiffuseColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()*3/4, 64 + col.Green()*3/4, 64 + col.Blue()*3/4); |
345 | 350 | Material.EmissiveColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()/2, 64 + col.Green()/2, 64 + col.Blue()/2); |
351 | + Material.Shininess = Selected ? 0.0f : 64.0f; | |
346 | 352 | |
347 | 353 | using namespace irr::core; |
348 | 354 | video::IVideoDriver* driver = SceneManager->getVideoDriver(); |
@@ -359,7 +365,10 @@ | ||
359 | 365 | if (wire_mode != 1 && wire_mode != 2) return; |
360 | 366 | |
361 | 367 | WMaterial.Thickness = Selected ? 3.0f : 1.0f; |
368 | + WMaterial.SpecularColor.set(0, 0, 0, 0); | |
362 | 369 | WMaterial.AmbientColor.set(0, 0, 0, 0); |
370 | + WMaterial.DiffuseColor.set(0, 0, 0, 0); | |
371 | + WMaterial.EmissiveColor.set(0, 0, 0, 0); | |
363 | 372 | driver->setMaterial(WMaterial); |
364 | 373 | |
365 | 374 | u32 *pWIndices = 0, cntWIndices = 0; |
@@ -26,6 +26,8 @@ | ||
26 | 26 | #pragma comment(lib, "Irrlicht.lib") |
27 | 27 | #endif |
28 | 28 | |
29 | +#define ENABLE_CUSTOM_SHADER | |
30 | + | |
29 | 31 | // type ... 2: Lines、3: Triangles |
30 | 32 | bool ExtractIntersectedElements(const ON_BoundingBox &bb, const S3DVertex *vertices, u32 numVertices, const u32 *indices, u32 numIndices, s32 type, array<u32> &extracted){ |
31 | 33 | if (type < 2 || type > 3) return false; |
@@ -295,6 +297,7 @@ | ||
295 | 297 | s32 WindowWidth, WindowHeight; |
296 | 298 | vector3df EyePos, TargetPos, UpVector; |
297 | 299 | CONObjSceneNode::RenderingMode rendering_mode; |
300 | + video::E_MATERIAL_TYPE ShaderMaterial; | |
298 | 301 | |
299 | 302 | // === Implement of IEventReceiver === |
300 | 303 | virtual bool OnEvent(const SEvent& event) |
@@ -360,13 +363,13 @@ | ||
360 | 363 | s32 id = event.GUIEvent.Caller->getID(); |
361 | 364 | std::fprintf(stderr, "CheckBoxChanged:%d\n", id); |
362 | 365 | bool checked = static_cast<gui::IGUICheckBox*>(event.GUIEvent.Caller)->isChecked(); |
363 | - --id; | |
364 | - for (list<Group>::Iterator iter = groups.begin(); iter != groups.end() && id >= 0; ++iter, --id){ | |
365 | - if (id == 0){ | |
366 | - iter->showflag = checked; | |
367 | - view_to_update = true; | |
368 | - break; | |
369 | - } | |
366 | + s32 cnt_iter = std::abs(id); | |
367 | + list<CONObjSceneNode::Group>::Iterator iter = groups.begin(); | |
368 | + for (s32 i = 1; i < cnt_iter && iter != groups.end(); ++i) ++iter; | |
369 | + if (iter != groups.end()){ | |
370 | + if (id > 0) iter->showflag = checked; | |
371 | + else iter->force_groupcolor = checked; | |
372 | + view_to_update = true; | |
370 | 373 | } |
371 | 374 | } |
372 | 375 |
@@ -421,7 +424,7 @@ | ||
421 | 424 | printf("Hit %u nodes from grid \n", res.sceneNodes.size()); |
422 | 425 | for (u32 i = 0; i < res.sceneNodes.size(); ++i){ |
423 | 426 | CONObjSceneNode *sn = res.sceneNodes[i]; |
424 | - if (!(*sn->show_flag)) continue; | |
427 | + if (!sn->group->showflag) continue; | |
425 | 428 | array<u32> &extr_by_bb = extr_by_bbs[sn]; |
426 | 429 | ExtractIntersectedElements(res.box, &sn->Vertices[0], sn->Vertices.size(), |
427 | 430 | &sn->Indices[0], sn->Indices.size(), 3, extr_by_bb); |
@@ -434,7 +437,7 @@ | ||
434 | 437 | array<u32> &extr_by_bb = iter->second; |
435 | 438 | if (extr_by_bb.size() == 0) continue; |
436 | 439 | CONObjSceneNode *sn = iter->first; |
437 | - if (!(*sn->show_flag)) continue; | |
440 | + if (!sn->group->showflag) continue; | |
438 | 441 | array<u32> extr_by_ray; |
439 | 442 | array<f32> distance; |
440 | 443 | ExtractIntersectedElements(ray, 0.0625f, &sn->Vertices[0], sn->Vertices.size(), |
@@ -446,6 +449,9 @@ | ||
446 | 449 | if (sn_nearest){ |
447 | 450 | if (operation == Select){ |
448 | 451 | sn_nearest->Selected = (sn_nearest->Selected) ? false : true; |
452 | + if (sn_nearest->Selected){ | |
453 | + std::wprintf(L"%s selected\n", sn_nearest->ONAttribute.m_name.Array()); | |
454 | + } | |
449 | 455 | }else if (operation == SetCenter){ |
450 | 456 | TargetPos = EyePos + ZDir * dist_min + XDir * dx + YDir * dy; |
451 | 457 | EyePos = TargetPos - ZDir * distEye2Target; |
@@ -496,10 +502,10 @@ | ||
496 | 502 | } |
497 | 503 | |
498 | 504 | bool Initialize(){ |
499 | - // ask user for driver | |
500 | - video::E_DRIVER_TYPE driverType = driverChoiceConsole(); | |
501 | - if (driverType == video::EDT_COUNT) return false; | |
502 | - | |
505 | + if (!irr::IrrlichtDevice::isDriverSupported(irr::video::EDT_OPENGL)){ | |
506 | + std::fprintf(stderr, "Error: OpenGL not supported.\n"); | |
507 | + return false; | |
508 | + } | |
503 | 509 | // CameraWidth : CameraHeight = WindowWidth : WindowHeight に |
504 | 510 | // しないと表示の縦横比が1:1にならない。 |
505 | 511 | WindowWidth = 640; |
@@ -509,7 +515,7 @@ | ||
509 | 515 | Device = 0; |
510 | 516 | { |
511 | 517 | SIrrlichtCreationParameters p; |
512 | - p.DriverType = driverType; | |
518 | + p.DriverType = video::EDT_OPENGL; | |
513 | 519 | p.WindowSize = core::dimension2d<u32>(WindowWidth, WindowHeight); |
514 | 520 | p.Bits = 16; |
515 | 521 | p.Fullscreen = false; |
@@ -525,7 +531,7 @@ | ||
525 | 531 | |
526 | 532 | // create engine |
527 | 533 | |
528 | - Device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo"); | |
534 | + Device->setWindowCaption(L"Mesh Viewer"); | |
529 | 535 | Device->setResizable(true); |
530 | 536 | |
531 | 537 | Driver = Device->getVideoDriver(); |
@@ -538,6 +544,35 @@ | ||
538 | 544 | col.setAlpha(128); |
539 | 545 | skin->setColor(static_cast<gui::EGUI_DEFAULT_COLOR>(i), col); |
540 | 546 | } |
547 | + | |
548 | + // シェーダ設定 | |
549 | + ShaderMaterial = video::EMT_SOLID; | |
550 | +#ifdef ENABLE_CUSTOM_SHADER | |
551 | + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0) && | |
552 | + Driver->queryFeature(video::EVDF_VERTEX_SHADER_2_0)){ | |
553 | + | |
554 | + video::IGPUProgrammingServices* gpu = Driver->getGPUProgrammingServices(); | |
555 | + ShaderMaterial = static_cast<video::E_MATERIAL_TYPE>(gpu->addHighLevelShaderMaterial( | |
556 | + "varying vec3 v_mdlpos;" | |
557 | + "void main(void) {" | |
558 | + " v_mdlpos = gl_ModelViewMatrix * gl_Vertex;" | |
559 | + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" | |
560 | + "}", | |
561 | + "main", video::EVST_VS_2_0, | |
562 | + "varying vec3 v_mdlpos;" | |
563 | + "void main (void) {" | |
564 | + " vec3 fnrm = normalize(cross(dFdx(v_mdlpos),dFdy(v_mdlpos)));" | |
565 | + " float intensity = abs(max(1.0f - ceil(gl_FrontMaterial.shininess / 128.0f), fnrm.z)) * 1.6 + 0.4;" | |
566 | + " gl_FragColor = gl_FrontMaterial.emission * intensity;" // emission はノードで col / 2 と設定しているから 0.0 〜 2.0の範囲でちょうどいい | |
567 | +// " gl_FragColor = vec4(0.0, intensity, 0.0, 1.0);" | |
568 | + "}", | |
569 | + "main", video::EPST_PS_2_0, | |
570 | + 0, video::EMT_SOLID, 0, EGSL_DEFAULT | |
571 | + )); | |
572 | + std::fprintf(stderr, "Shader Material:%d\n", ShaderMaterial); | |
573 | + } | |
574 | +#endif | |
575 | + | |
541 | 576 | return true; |
542 | 577 | } |
543 | 578 |
@@ -548,9 +583,10 @@ | ||
548 | 583 | IGUITab* showhideTab = tabctrl->addTab(L"Show/Hide"); |
549 | 584 | int idx = 1; |
550 | 585 | int wy = 5, height = 20; |
551 | - for (list<Group>::ConstIterator iter = groups.begin(); iter != groups.end(); ++iter, ++idx, wy += height){ | |
552 | - const Group &gr = *iter; | |
553 | - GUIEnv->addCheckBox(gr.showflag, core::rect<int>( 5, wy, 140, wy + height), showhideTab, idx, ON_wString(gr.name)); | |
586 | + for (list<CONObjSceneNode::Group>::ConstIterator iter = groups.begin(); iter != groups.end(); ++iter, ++idx, wy += height){ | |
587 | + const CONObjSceneNode::Group &gr = *iter; | |
588 | + GUIEnv->addCheckBox(gr.force_groupcolor, core::rect<int>( 5, wy, 30, wy + height), showhideTab, -idx, 0); | |
589 | + GUIEnv->addCheckBox(gr.showflag, core::rect<int>( 35, wy, 140, wy + height), showhideTab, idx, ON_wString(gr.name)); | |
554 | 590 | } |
555 | 591 | } |
556 | 592 |
@@ -559,21 +595,34 @@ | ||
559 | 595 | } |
560 | 596 | |
561 | 597 | void addSceneNodes(ONX_Model &model, ON_String name){ |
562 | - groups.push_back(Group()); | |
563 | - Group &gr = *groups.getLast(); | |
598 | + groups.push_back(CONObjSceneNode::Group()); | |
599 | + CONObjSceneNode::Group &gr = *groups.getLast(); | |
564 | 600 | gr.name = name; |
565 | 601 | gr.showflag = true; |
602 | + gr.force_groupcolor = false; | |
566 | 603 | |
567 | 604 | aabbox3d<f32> bbox; |
568 | 605 | |
569 | 606 | int count = 0; |
570 | 607 | |
608 | + static ON_Color colors[] = { | |
609 | + ON_Color(255, 0, 128), ON_Color( 0, 255, 0), ON_Color( 0, 255, 255), ON_Color(0, 128, 0), ON_Color(255, 0, 255), ON_Color(0, 0, 255), ON_Color(0, 0, 0), ON_Color(0xFFFFFFFF) | |
610 | + }; | |
611 | + static int colsize = 0; | |
612 | + static int colidx = 0; | |
613 | + if (colsize == 0){ | |
614 | + while(colors[colsize] != 0xFFFFFFFF) ++colsize; | |
615 | + } | |
616 | + gr.group_color = colors[(groups.size()-1)%colsize]; | |
617 | + | |
571 | 618 | // 形状設定 |
572 | 619 | for (s32 j = 0; j < model.m_object_table.Count(); ++j){ |
573 | 620 | const ON_Mesh *mesh = ON_Mesh::Cast(model.m_object_table[j].m_object); |
574 | 621 | if (!mesh) continue; |
575 | 622 | if (mesh->m_V.Count() == 0) continue; |
576 | - CONObjSceneNode *myNode = new CONObjSceneNode(&model, mesh, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666, vector3df(0,0,1), 2, &rendering_mode, &gr.showflag); | |
623 | + model.m_object_table[j].m_attributes.m_color = colors[colidx++]; | |
624 | + if (colors[colidx] == 0xFFFFFFFF) colidx = 0; | |
625 | + CONObjSceneNode *myNode = new CONObjSceneNode(&model, mesh, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666, vector3df(0,0,1), 2, &rendering_mode, &gr, ShaderMaterial); | |
577 | 626 | |
578 | 627 | #if 0 |
579 | 628 | const ON_Mesh *mesh = ON_Mesh::Cast(model.m_object_table[j].m_object); |
@@ -707,10 +756,10 @@ | ||
707 | 756 | |
708 | 757 | if (++frames == 100) |
709 | 758 | { |
710 | - core::stringw str = L"Irrlicht Engine ["; | |
711 | - str += Driver->getName(); | |
712 | - str += L"] FPS: "; | |
759 | + core::stringw str = L"Mesh Viewer ("; | |
760 | + str += L" FPS: "; | |
713 | 761 | str += (s32)Driver->getFPS(); |
762 | + str += ")"; | |
714 | 763 | |
715 | 764 | Device->setWindowCaption(str.c_str()); |
716 | 765 | frames=0; |
@@ -726,11 +775,7 @@ | ||
726 | 775 | ISceneManager *Smgr; |
727 | 776 | gui::IGUIEnvironment *GUIEnv; |
728 | 777 | |
729 | - struct Group{ | |
730 | - ON_String name; | |
731 | - bool showflag; | |
732 | - }; | |
733 | - list<Group> groups; | |
778 | + list<CONObjSceneNode::Group> groups; | |
734 | 779 | CGridSelector Selector; |
735 | 780 | array<ILightSceneNode *> LightNodes; |
736 | 781 | array<CONObjSceneNode *> CustomNodes; |