diff --git a/radiant/ui/common/ShaderSelector.cpp b/radiant/ui/common/ShaderSelector.cpp index 9de0d8096d..92ea0a2165 100644 --- a/radiant/ui/common/ShaderSelector.cpp +++ b/radiant/ui/common/ShaderSelector.cpp @@ -137,9 +137,11 @@ void ShaderSelector::createTreeView() _treeView->Populate(std::make_shared(_shaderTreeColumns, _prefixes)); } -// Create the preview panel (GL widget and info table) void ShaderSelector::createPreview() { + _previewCombo = new TexturePreviewCombo(this); + GetSizer()->Add(_previewCombo, 0, wxEXPAND | wxTOP, 3); +#if 0 // HBox contains the preview GL widget along with a texture attributes pane. wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); @@ -162,16 +164,18 @@ void ShaderSelector::createPreview() sizer->Add(tree, 1, wxEXPAND); GetSizer()->Add(sizer, 0, wxEXPAND | wxTOP, 3); +#endif } -// Get the selected shader -MaterialPtr ShaderSelector::getSelectedShader() { +MaterialPtr ShaderSelector::getSelectedShader() +{ return GlobalMaterialManager().getMaterial(getSelection()); } // Update the attributes table void ShaderSelector::updateInfoTable() { + return; _infoStore->Clear(); // Get the selected texture name. If nothing is selected, we just leave the @@ -188,6 +192,8 @@ void ShaderSelector::updateInfoTable() // Callback to redraw the GL widget bool ShaderSelector::onPreviewRender() { + return true; + // Get the viewport size from the GL widget wxSize req = _glWidget->GetClientSize(); @@ -332,8 +338,12 @@ void ShaderSelector::displayLightShaderInfo(const MaterialPtr& shader, // Callback for selection changed void ShaderSelector::_onSelChange(wxDataViewEvent& ev) { + _previewCombo->SetTexture(getSelection()); +#if 0 updateInfoTable(); _glWidget->Refresh(); + +#endif } } // namespace ui diff --git a/radiant/ui/common/ShaderSelector.h b/radiant/ui/common/ShaderSelector.h index 147b9a676f..105bfe543f 100644 --- a/radiant/ui/common/ShaderSelector.h +++ b/radiant/ui/common/ShaderSelector.h @@ -10,6 +10,8 @@ #include +#include "TexturePreviewCombo.h" + // FORWARD DECLS class Material; typedef std::shared_ptr MaterialPtr; @@ -96,6 +98,8 @@ class ShaderSelector : InfoStoreColumns _infoStoreColumns; + TexturePreviewCombo* _previewCombo; + // List store for info table wxutil::TreeModel::Ptr _infoStore; diff --git a/radiant/ui/common/TexturePreviewCombo.cpp b/radiant/ui/common/TexturePreviewCombo.cpp index 5c1b8f2c4f..3e67f6b5e3 100644 --- a/radiant/ui/common/TexturePreviewCombo.cpp +++ b/radiant/ui/common/TexturePreviewCombo.cpp @@ -4,7 +4,7 @@ #include "wxutil/menu/IconTextMenuItem.h" #include "wxutil/GLWidget.h" #include "wxutil/dataview/KeyValueTable.h" -#include "wxutil/dataview/TreeModel.h" +#include "gamelib.h" #include "ishaders.h" #include "texturelib.h" @@ -18,21 +18,23 @@ namespace ui { -// Constructor. Create widgets. +namespace +{ + constexpr const char* const LIGHT_PREFIX_XPATH = "/light/texture//prefix"; +} TexturePreviewCombo::TexturePreviewCombo(wxWindow* parent) : wxPanel(parent, wxID_ANY), _glWidget(new wxutil::GLWidget(this, std::bind(&TexturePreviewCombo::_onRender, this), "TexturePreviewCombo")), _texName(""), - _infoTable(NULL), + _infoTable(nullptr), _contextMenu(new wxutil::PopupMenu) { _glWidget->SetMinSize(wxSize(128, 128)); // Add info table _infoTable = new wxutil::KeyValueTable(this); - _infoTable->Connect(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, - wxDataViewEventHandler(TexturePreviewCombo::_onContextMenu), NULL, this); + _infoTable->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, &TexturePreviewCombo::_onContextMenu, this); SetSizer(new wxBoxSizer(wxHORIZONTAL)); @@ -44,6 +46,8 @@ TexturePreviewCombo::TexturePreviewCombo(wxWindow* parent) : new wxutil::StockIconTextMenuItem(_("Copy shader name"), wxART_COPY), std::bind(&TexturePreviewCombo::_onCopyTexName, this) ); + + loadLightTexturePrefixes(); } // Update the selected texture @@ -75,11 +79,38 @@ void TexturePreviewCombo::refreshInfoTable() } // Get shader info - MaterialPtr shader = GlobalMaterialManager().getMaterial(_texName); + auto shader = GlobalMaterialManager().getMaterial(_texName); + // Regular shader info _infoTable->Append(_("Shader"), shader->getName()); _infoTable->Append(_("Defined in"), shader->getShaderFileName()); - _infoTable->Append(_("Description"), shader->getDescription()); + + auto descr = shader->getDescription(); + _infoTable->Append(_("Description"), descr.empty() ? "-" : descr); + + if (isLightTexture()) + { + auto first = shader->firstLayer(); + + if (first) + { + auto tex = shader->firstLayer()->getTexture(); + _infoTable->Append(_("Image map"), tex->getName()); + } + + // Light types, from the Material + std::string lightType; + if (shader->isAmbientLight()) + lightType.append("ambient "); + if (shader->isBlendLight()) + lightType.append("blend "); + if (shader->isFogLight()) + lightType.append("fog"); + if (lightType.empty()) + lightType.append("-"); + + _infoTable->Append(_("Light flags"), lightType); + } _infoTable->TriggerColumnSizeEvent(); } @@ -105,11 +136,10 @@ void TexturePreviewCombo::_onContextMenu(wxDataViewEvent& ev) _contextMenu->show(_infoTable); } -// CALLBACKS bool TexturePreviewCombo::_onRender() { // Get the viewport size from the GL widget - wxSize req = _glWidget->GetClientSize(); + auto req = _glWidget->GetClientSize(); if (req.GetWidth() == 0 || req.GetHeight() == 0) return false; @@ -132,28 +162,37 @@ bool TexturePreviewCombo::_onRender() if (!_texName.empty()) { // Get a reference to the selected shader - MaterialPtr shader = GlobalMaterialManager().getMaterial(_texName); + auto shader = GlobalMaterialManager().getMaterial(_texName); + + // This is an "ordinary" texture, take the editor image + auto tex = shader->getEditorImage(); - // This is an "ordinary" texture, take the editor image - TexturePtr tex = shader->getEditorImage(); + if (isLightTexture()) + { + // This is a light, take the first layer texture + if (auto first = shader->firstLayer(); first) + { + tex = shader->firstLayer()->getTexture(); + } + } - if (tex != NULL) + if (tex) { glBindTexture(GL_TEXTURE_2D, tex->getGLTexNum()); // Calculate the correct aspect ratio for preview - float aspect = float(tex->getWidth()) / float(tex->getHeight()); + auto aspect = static_cast(tex->getWidth()) / tex->getHeight(); float hfWidth, hfHeight; if (aspect > 1.0f) { - hfWidth = 0.5 * req.GetWidth(); - hfHeight = 0.5 * req.GetHeight() / aspect; + hfWidth = 0.5f * req.GetWidth(); + hfHeight = 0.5f * req.GetHeight() / aspect; } else { - hfHeight = 0.5 * req.GetWidth(); - hfWidth = 0.5 * req.GetHeight() * aspect; + hfHeight = 0.5f * req.GetWidth(); + hfWidth = 0.5f * req.GetHeight() * aspect; } // Draw a quad to put the texture on @@ -162,13 +201,13 @@ bool TexturePreviewCombo::_onRender() glBegin(GL_QUADS); glTexCoord2i(0, 1); - glVertex2f(0.5*req.GetWidth() - hfWidth, 0.5*req.GetHeight() - hfHeight); + glVertex2f(0.5f*req.GetWidth() - hfWidth, 0.5f*req.GetHeight() - hfHeight); glTexCoord2i(1, 1); - glVertex2f(0.5*req.GetWidth() + hfWidth, 0.5*req.GetHeight() - hfHeight); + glVertex2f(0.5f*req.GetWidth() + hfWidth, 0.5f*req.GetHeight() - hfHeight); glTexCoord2i(1, 0); - glVertex2f(0.5*req.GetWidth() + hfWidth, 0.5*req.GetHeight() + hfHeight); + glVertex2f(0.5f*req.GetWidth() + hfWidth, 0.5f*req.GetHeight() + hfHeight); glTexCoord2i(0, 0); - glVertex2f(0.5*req.GetWidth() - hfWidth, 0.5*req.GetHeight() + hfHeight); + glVertex2f(0.5f*req.GetWidth() - hfWidth, 0.5f*req.GetHeight() + hfHeight); glEnd(); } } @@ -178,4 +217,29 @@ bool TexturePreviewCombo::_onRender() return true; } +void TexturePreviewCombo::loadLightTexturePrefixes() +{ + // Get the list of light texture prefixes from the registry + auto prefList = game::current::getNodes(LIGHT_PREFIX_XPATH); + + // Copy the Node contents into the prefix vector + for (const auto& node : prefList) + { + _lightTexturePrefixes.push_back(node.getContent() + "/"); + } +} + +bool TexturePreviewCombo::isLightTexture() +{ + for (const auto& prefix : _lightTexturePrefixes) + { + if (string::istarts_with(_texName, prefix)) + { + return true; + } + } + + return false; +} + } diff --git a/radiant/ui/common/TexturePreviewCombo.h b/radiant/ui/common/TexturePreviewCombo.h index 10c775b805..5e5eb5e695 100644 --- a/radiant/ui/common/TexturePreviewCombo.h +++ b/radiant/ui/common/TexturePreviewCombo.h @@ -34,6 +34,8 @@ class TexturePreviewCombo : // Context menu wxutil::PopupMenuPtr _contextMenu; + std::vector _lightTexturePrefixes; + public: /** Constructor creates widgets. @@ -59,6 +61,10 @@ class TexturePreviewCombo : // Popupmenu event void _onContextMenu(wxDataViewEvent& ev); + + void loadLightTexturePrefixes(); + + bool isLightTexture(); }; } // namespace