diff --git a/code/nel/include/nel/3d/shader_manager.h b/code/nel/include/nel/3d/shader_manager.h index 5207bdc86..7158a5ea4 100644 --- a/code/nel/include/nel/3d/shader_manager.h +++ b/code/nel/include/nel/3d/shader_manager.h @@ -34,8 +34,10 @@ namespace NL3D ~CShaderManager(); void clear(); void getShaderList( std::vector< std::string > &v ); - void addShader( CShaderProgram *program ); - void changeShader( const std::string &name, CShaderProgram *program ); + bool addShader( CShaderProgram *program ); + bool removeShader( const std::string &name ); + bool changeShader( const std::string &name, CShaderProgram *program ); + bool getShader( const std::string &name, CShaderProgram *program ); void visitShaders( IShaderVisitor *visitor ); void visitShader( const std::string &name, IShaderVisitor *visitor ); diff --git a/code/nel/include/nel/3d/shader_program.h b/code/nel/include/nel/3d/shader_program.h index 963784cb3..4f635a7da 100644 --- a/code/nel/include/nel/3d/shader_program.h +++ b/code/nel/include/nel/3d/shader_program.h @@ -41,8 +41,8 @@ namespace NL3D void setName( const std::string &n ){ name = n; } void setDescription( const std::string &d ){ description = d; } - void setVP( std::string &vp ){ vertexProgram = vp; } - void setFP( std::string &fp ){ fragmentProgram = fp; } + void setVP( const std::string &vp ){ vertexProgram = vp; } + void setFP( const std::string &fp ){ fragmentProgram = fp; } uint32 getVPId() const{ return vpId; } uint32 getFPId() const{ return fpId; } diff --git a/code/nel/src/3d/shader_manager.cpp b/code/nel/src/3d/shader_manager.cpp index 8dd8332c3..3236aa280 100644 --- a/code/nel/src/3d/shader_manager.cpp +++ b/code/nel/src/3d/shader_manager.cpp @@ -56,7 +56,7 @@ namespace NL3D } } - void CShaderManager::addShader( CShaderProgram *program ) + bool CShaderManager::addShader( CShaderProgram *program ) { std::string n; program->getName( n ); @@ -64,20 +64,34 @@ namespace NL3D std::tr1::unordered_map< std::string, CShaderProgram* >::iterator itr = programs.find( n ); if( itr != programs.end() ) - return; + return false; programs[ n ] = program; + return true; } - void CShaderManager::changeShader( const std::string &name, CShaderProgram *program ) + bool CShaderManager::removeShader( const std::string &name ) { std::tr1::unordered_map< std::string, CShaderProgram* >::iterator itr = programs.find( name ); if( itr == programs.end() ) - return; + return false; - CShaderProgram *p = itr->second; + delete itr->second; + itr->second = NULL; + programs.erase( itr ); + return true; + } + + bool CShaderManager::changeShader( const std::string &name, CShaderProgram *program ) + { + std::tr1::unordered_map< std::string, CShaderProgram* >::iterator itr + = programs.find( name ); + if( itr == programs.end() ) + return false; + + CShaderProgram *p = itr->second; std::string s; program->getName( s ); @@ -91,7 +105,32 @@ namespace NL3D program->getFP( s ); p->setFP( s ); + + return true; + } + + bool CShaderManager::getShader( const std::string &name, CShaderProgram *program ) + { + std::tr1::unordered_map< std::string, CShaderProgram* >::iterator itr + = programs.find( name ); + if( itr == programs.end() ) + return false; + + CShaderProgram *p = itr->second; + std::string s; + + program->setName( name ); + p->getDescription( s ); + program->setDescription( s ); + + p->getVP( s ); + program->setVP( s ); + + p->getFP( s ); + program->setFP( s ); + + return true; } void CShaderManager::visitShaders( IShaderVisitor *visitor ) diff --git a/code/nel/src/3d/shader_program.cpp b/code/nel/src/3d/shader_program.cpp index d6b952d18..9ea9ba7ed 100644 --- a/code/nel/src/3d/shader_program.cpp +++ b/code/nel/src/3d/shader_program.cpp @@ -23,6 +23,7 @@ namespace NL3D { vpId = 0; fpId = 0; + pId = 0; } CShaderProgram::~CShaderProgram() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_editor_window.cpp index d72e7c7fa..ddde7059e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_editor_window.cpp @@ -44,6 +44,7 @@ namespace MaterialEditor nl3dIface = new CNel3DInterface(); shaderWidget = new ShaderWidget(); + shaderWidget->setNel3DInterface( nl3dIface ); materialSplitter = new MaterialSplitter(); materialSplitter->setNel3DIface( nl3dIface ); passesWidget = new RenderPassesWidget(); @@ -139,6 +140,7 @@ namespace MaterialEditor void MaterialEditorWindow::onShadersClicked() { + shaderWidget->load(); shaderWidget->show(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp index 6eb588c1a..5c83cc1d4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.cpp @@ -16,6 +16,8 @@ #include "nel3d_interface.h" #include "nel/3d/dynamic_material.h" +#include "nel/3d/shader_manager.h" +#include "nel/3d/shader_program.h" #include "nel/misc/i_xml.h" #include "nel/misc/o_xml.h" #include "nel/misc/file.h" @@ -180,10 +182,14 @@ namespace MaterialEditor CNel3DInterface::CNel3DInterface() { mat = new NL3D::CDynMaterial(); + shaderManager = new NL3D::CShaderManager(); + } CNel3DInterface::~CNel3DInterface() { + delete shaderManager; + shaderManager = NULL; } bool CNel3DInterface::loadMaterial( const char *fname ) @@ -232,5 +238,67 @@ namespace MaterialEditor { return CNelMaterialProxy( mat ); } + + void CNel3DInterface::getShaderList( std::vector< std::string > &v ) + { + shaderManager->getShaderList( v ); + } + + bool CNel3DInterface::getShaderInfo( const std::string &name, SShaderInfo &info ) + { + NL3D::CShaderProgram program; + bool ok = shaderManager->getShader( name, &program ); + if( !ok ) + return false; + + std::string s; + info.name = name; + + program.getDescription( s ); + info.description = s; + + program.getVP( s ); + info.vp = s; + + program.getFP( s ); + info.fp = s; + + return true; + } + + bool CNel3DInterface::updateShaderInfo( const SShaderInfo &info ) + { + NL3D::CShaderProgram program; + program.setName( info.name ); + program.setDescription( info.description ); + program.setVP( info.vp ); + program.setFP( info.fp ); + + return shaderManager->changeShader( info.name, &program ); + } + + bool CNel3DInterface::addShader( const SShaderInfo &info ) + { + NL3D::CShaderProgram *program = new NL3D::CShaderProgram(); + + program->setName( info.name ); + program->setDescription( info.description ); + program->setVP( info.vp ); + program->setFP( info.fp ); + + bool ok = shaderManager->addShader( program ); + if( !ok ) + { + delete program; + return false; + } + + return true; + } + + bool CNel3DInterface::removeShader( const std::string &name ) + { + return shaderManager->removeShader( name ); + } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.h index c95bcdb3d..167381b7b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/nel3d_interface.h @@ -25,6 +25,7 @@ namespace NL3D { class CDynMaterial; struct SRenderPass; + class CShaderManager; } namespace MaterialEditor @@ -106,6 +107,14 @@ namespace MaterialEditor }; + struct SShaderInfo + { + std::string name; + std::string description; + std::string vp; + std::string fp; + }; + /// Proxy class for Nel3D, so the material editor and Nel3D can interface class CNel3DInterface { @@ -119,8 +128,16 @@ namespace MaterialEditor CNelMaterialProxy getMaterial(); + + void getShaderList( std::vector< std::string > &v ); + bool getShaderInfo( const std::string &name, SShaderInfo &info ); + bool updateShaderInfo( const SShaderInfo &info ); + bool addShader( const SShaderInfo &info ); + bool removeShader( const std::string &name ); + private: NL3D::CDynMaterial *mat; + NL3D::CShaderManager *shaderManager; }; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_editor.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_editor.ui index 48f87f534..73d57b975 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_editor.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_editor.ui @@ -27,7 +27,11 @@ - + + + false + + @@ -117,13 +121,6 @@ - layoutWidget - layoutWidget_2 - layoutWidget_3 - layoutWidget_4 - layoutWidget_5 - vsEdit - label_3 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.cpp index 309da0ca8..cf30a0abe 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.cpp @@ -16,6 +16,7 @@ #include "shader_widget.h" #include "shader_editor.h" +#include "nel3d_interface.h" #include #include #include @@ -29,6 +30,7 @@ namespace MaterialEditor setupConnections(); shaderEditorWidget = new ShaderEditorWidget(); + nl3dIface = NULL; } ShaderWidget::~ShaderWidget() @@ -37,6 +39,22 @@ namespace MaterialEditor shaderEditorWidget = NULL; } + void ShaderWidget::load() + { + std::vector< std::string > v; + + nl3dIface->getShaderList( v ); + + shaderList->clear(); + + std::vector< std::string >::const_iterator itr = v.begin(); + while( itr != v.end() ) + { + shaderList->addItem( itr->c_str() ); + ++itr; + } + } + void ShaderWidget::setupConnections() { connect( okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); @@ -44,6 +62,8 @@ namespace MaterialEditor connect( addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) ); connect( removeButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveClicked() ) ); connect( editButton, SIGNAL( clicked( bool ) ), this, SLOT( onEditClicked() ) ); + + connect( shaderList, SIGNAL( currentRowChanged( int ) ), this, SLOT( onRowChanged( int ) ) ); } void ShaderWidget::onOKClicked() @@ -98,6 +118,20 @@ namespace MaterialEditor return; } + SShaderInfo info; + info.name = name.toUtf8().data(); + bool ok = nl3dIface->addShader( info ); + if( !ok ) + { + QMessageBox::critical( + this, + tr( "Error adding shader" ), + tr( "There was an error while trying to add the shader" ) + ); + + return; + } + shaderList->addItem( name ); } @@ -119,8 +153,11 @@ namespace MaterialEditor if( selection == QMessageBox::Yes ) { QListWidgetItem *item = shaderList->takeItem( i ); + std::string n = item->text().toUtf8().data(); delete item; + nl3dIface->removeShader( n ); } + } void ShaderWidget::onEditClicked() @@ -132,34 +169,66 @@ namespace MaterialEditor QString name = shaderList->item( i )->text(); shaderEditorWidget->reset(); - shaderEditorWidget->setName( name ); + + SShaderInfo info; + std::string n = name.toUtf8().data(); + bool ok = nl3dIface->getShaderInfo( n, info ); + if( !ok ) + { + QMessageBox::critical( + this, + tr( "Error retrieving shader data" ), + tr( "There was an error while trying to retrieve shader data!" ) + ); - QString sname; - bool ok; - int res; - do{ - ok = true; - res = shaderEditorWidget->exec(); - if( res == QDialog::Rejected ) - return; + return; + } - shaderEditorWidget->getName( sname ); + shaderEditorWidget->setName( info.name.c_str() ); + shaderEditorWidget->setDescription( info.description.c_str() ); + shaderEditorWidget->setVertexShader( info.vp.c_str() ); + shaderEditorWidget->setFragmentShader( info.fp.c_str() ); - if( sname != name ) - { - if( nameExists( sname ) ) - { - ok = false; - nameExistsMessage(); - } - } + int res = shaderEditorWidget->exec(); + if( res == QDialog::Rejected ) + return; - }while( !ok ); + // save + QString s; - shaderList->item( i )->setText( sname ); + shaderEditorWidget->getDescription( s ); + info.description = s.toUtf8().data(); - // save + shaderEditorWidget->getVertexShader( s ); + info.vp = s.toUtf8().data(); + + shaderEditorWidget->getFragmentShader( s ); + info.fp = s.toUtf8().data(); + + ok = nl3dIface->updateShaderInfo( info ); + if( !ok ) + { + QMessageBox::critical( + this, + tr( "Error saving shader data" ), + tr( "There was an error while trying to save shader data!" ) + ); + } + } + + void ShaderWidget::onRowChanged( int i ) + { + if( i < 0 ) + return; + + std::string s = shaderList->item( i )->text().toUtf8().data(); + + SShaderInfo info; + bool ok = nl3dIface->getShaderInfo( s, info ); + if( !ok ) + return; + description->setPlainText( info.description.c_str() ); } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.h index bc5236f8d..cbfb3bcd5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/shader_widget.h @@ -23,6 +23,7 @@ namespace MaterialEditor { class ShaderEditorWidget; + class CNel3DInterface; class ShaderWidget : public QWidget, public Ui::ShaderWidget { @@ -32,18 +33,23 @@ namespace MaterialEditor ShaderWidget( QWidget *parent = NULL ); ~ShaderWidget(); + void setNel3DInterface( CNel3DInterface *iface ){ nl3dIface = iface; } + void load(); + private: void setupConnections(); bool nameExists( const QString &name ); void nameExistsMessage(); ShaderEditorWidget *shaderEditorWidget; + CNel3DInterface *nl3dIface; private Q_SLOTS: void onOKClicked(); void onAddClicked(); void onRemoveClicked(); void onEditClicked(); + void onRowChanged( int i ); }; }