From 37fb2cfcdafdcb95c7bac1bc77dd377435834f8a Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Thu, 18 Jul 2013 00:14:17 +0200 Subject: [PATCH] Started work on converting the old material to new one. Some colors are already out. Also made some modifications to the editor so it can deal with it. --HG-- branch : gsoc2013-dfighter --- code/nel/include/nel/3d/material.h | 11 ++ code/nel/include/nel/misc/rgba.h | 9 ++ code/nel/src/3d/material.cpp | 104 ++++++++++++++++++ .../material_editor_window.cpp | 4 +- .../material_editor/material_splitter.cpp | 6 + .../material_editor/material_splitter.h | 1 + .../material_editor/material_widget.cpp | 23 +++- .../plugins/material_editor/material_widget.h | 1 + .../material_editor/nel3d_interface.cpp | 44 +++++++- .../plugins/material_editor/nel3d_interface.h | 11 +- .../material_editor/prop_browser_ctrl.cpp | 73 +++++++++++- .../material_editor/prop_browser_ctrl.h | 1 + .../plugins/material_editor/render_passes.cpp | 15 +++ 13 files changed, 291 insertions(+), 12 deletions(-) diff --git a/code/nel/include/nel/3d/material.h b/code/nel/include/nel/3d/material.h index a7ca18bff..4da6875e0 100644 --- a/code/nel/include/nel/3d/material.h +++ b/code/nel/include/nel/3d/material.h @@ -33,6 +33,8 @@ using NLMISC::CRGBA; using NLMISC::CSmartPtr; using NLMISC::CRefPtr; +class CDynMaterial; + // -------------------------------------------------- const uint32 IDRV_MAT_MAXTEXTURES = 4; @@ -693,7 +695,16 @@ private: }; std::auto_ptr _TexUserMat; // user texture matrix + /// Dynamic material for the new driver + CDynMaterial *dynMat; + public: + + CDynMaterial* getDynMat() const{ return dynMat; } + + /// Create the dynamic material from the current material parameters + void createDynMat(); + // Private. For Driver only. CSmartPtr _Textures[IDRV_MAT_MAXTEXTURES]; uint8 _TexAddrMode[IDRV_MAT_MAXTEXTURES]; // texture addressing enum packed as bytes diff --git a/code/nel/include/nel/misc/rgba.h b/code/nel/include/nel/misc/rgba.h index db9ed892a..7b8539ea1 100644 --- a/code/nel/include/nel/misc/rgba.h +++ b/code/nel/include/nel/misc/rgba.h @@ -338,6 +338,15 @@ public: std::swap(R,B); } + /// Write the RGBA values to a float vector + void toFloatVector( float *v ) + { + v[ 0 ] = R; + v[ 1 ] = G; + v[ 2 ] = B; + v[ 3 ] = A; + } + /// Red componant. uint8 R; diff --git a/code/nel/src/3d/material.cpp b/code/nel/src/3d/material.cpp index 4f4386dc3..a1dee7c4a 100644 --- a/code/nel/src/3d/material.cpp +++ b/code/nel/src/3d/material.cpp @@ -20,6 +20,7 @@ #include "nel/3d/texture.h" #include "nel/3d/shader.h" #include "nel/3d/driver.h" +#include "nel/3d/dynamic_material.h" #include "nel/misc/stream.h" using namespace std; @@ -48,6 +49,7 @@ CMaterial::CMaterial() _AlphaTestThreshold= 0.5f; _TexCoordGenMode= 0; _LightMapsMulx2= false; + dynMat = NULL; } // *************************************************************************** @@ -120,6 +122,8 @@ CMaterial &CMaterial::operator=(const CMaterial &mat) // All states of material is modified. _Touched= IDRV_TOUCHED_ALL; + dynMat = NULL; + return *this; } @@ -134,6 +138,11 @@ CMaterial::~CMaterial() // Must kill the drv mirror of this material. _MatDrvInfo.kill(); + if( dynMat != NULL ) + { + delete dynMat; + dynMat = NULL; + } } @@ -168,6 +177,8 @@ void CMaterial::serial(NLMISC::IStream &f) - base version. */ + dynMat = NULL; + sint ver= f.serialVersion(9); // For the version <=1: nlassert(IDRV_MAT_MAXTEXTURES==4); @@ -624,5 +635,98 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const return false; } + +void CMaterial::createDynMat() +{ + if( dynMat == NULL ) + dynMat = new CDynMaterial(); + + SRenderPass *p = dynMat->getPass( 0 ); + + switch( _ShaderType ) + { + + case Normal: + p->setShaderRef( "Normal" ); + break; + + case Bump: + p->setShaderRef( "Bump" ); + break; + + case UserColor: + p->setShaderRef( "UserColor" ); + break; + + case LightMap: + p->setShaderRef( "LightMap" ); + break; + + case Specular: + p->setShaderRef( "Specular" ); + break; + + case Caustics: + p->setShaderRef( "Caustics" ); + break; + + case PerPixelLighting: + p->setShaderRef( "PerPixelLighting" ); + break; + + case PerPixelLightingNoSpec: + p->setShaderRef( "PerPixelLightingNoSpec" ); + break; + + case Cloud: + p->setShaderRef( "Cloud" ); + break; + + case Water: + p->setShaderRef( "Water" ); + break; + + default: + nlassert( false ); + break; + } + + float v[ 4 ]; + float m[ 16 ]; + SDynMaterialProp prop; + + prop.type = SDynMaterialProp::Color; + + prop.prop = "color"; + prop.label = "Color"; + _Color.toFloatVector( v ); + prop.value.setVector4( v ); + p->addProperty( prop ); + + prop.prop = "emissive"; + prop.label = "Emissive color"; + _Emissive.toFloatVector( v ); + prop.value.setVector4( v ); + p->addProperty( prop ); + + prop.prop = "ambient"; + prop.label = "Ambient color"; + _Ambient.toFloatVector( v ); + prop.value.setVector4( v ); + p->addProperty( prop ); + + prop.prop = "diffuse"; + prop.label = "Diffuse color"; + _Diffuse.toFloatVector( v ); + prop.value.setVector4( v ); + p->addProperty( prop ); + + prop.prop = "specular"; + prop.label = "Specular color"; + _Specular.toFloatVector( v ); + prop.value.setVector4( v ); + p->addProperty( prop ); +} + } 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 b92f5ef1c..77116381a 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 @@ -53,8 +53,8 @@ namespace MaterialEditor passesWidget = new RenderPassesWidget(); passesWidget->setMaterialObserver( materialSplitter ); passesWidget->setNel3dIface( nl3dIface ); - passesWidget->onMaterialLoaded(); - materialSplitter->onMaterialLoaded(); + //passesWidget->onMaterialLoaded(); + //materialSplitter->onMaterialLoaded(); createMenus(); createDockWidgets(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.cpp index 3d790afd5..76c6ac6ad 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.cpp @@ -48,6 +48,7 @@ namespace MaterialEditor { connect( materialWidget, SIGNAL( propsChanged() ), this, SLOT( onPropsChanged() ) ); connect( materialWidget, SIGNAL( passChanged( const QString& ) ), this, SLOT( onPassChanged( const QString& ) ) ); + connect( materialWidget, SIGNAL( subMatChanged( int ) ), this, SLOT( onSubMatChanged( int ) ) ); } void MaterialSplitter::setup() @@ -125,5 +126,10 @@ namespace MaterialEditor { browserCtrl->loadPropsForPass( pass ); } + + void MaterialSplitter::onSubMatChanged( int i ) + { + browserCtrl->loadPropsForPass( 0 ); + } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.h index 526975504..7bf7b96b9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_splitter.h @@ -64,6 +64,7 @@ namespace MaterialEditor private Q_SLOTS: void onPropsChanged(); void onPassChanged( const QString &pass ); + void onSubMatChanged( int i ); }; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.cpp index 8472b50b0..c5f4f9911 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.cpp @@ -49,6 +49,8 @@ namespace MaterialEditor void MaterialWidget::onMaterialLoaded() { CNelMaterialProxy mat = nl3dIface->getMaterial(); + if( mat.isEmpty() ) + return; std::vector< std::string > l; mat.getPassList( l ); @@ -177,7 +179,11 @@ namespace MaterialEditor if( passCB->count() == 0 ) return; - CRenderPassProxy p = nl3dIface->getMaterial().getPass( passCB->currentText().toUtf8().data() ); + CNelMaterialProxy m = nl3dIface->getMaterial(); + if( m.isEmpty() ) + return; + + CRenderPassProxy p = m.getPass( passCB->currentText().toUtf8().data() ); matPropWidget->load( &p ); matPropWidget->exec(); if( matPropWidget->getChanged() ) @@ -196,6 +202,15 @@ namespace MaterialEditor void MaterialWidget::onSubMatCBChanged( int i ) { // Update the material to the current submaterial + bool ok = nl3dIface->selectSubMaterial( i ); + if( !ok ) + { + subMatCB->setCurrentIndex( 0 ); + return; + } + + onMaterialLoaded(); + Q_EMIT subMatChanged( i ); } void MaterialWidget::onPassCBChanged( const QString &text ) @@ -204,6 +219,9 @@ namespace MaterialEditor return; CNelMaterialProxy m = nl3dIface->getMaterial(); + if( m.isEmpty() ) + return; + CRenderPassProxy pass = m.getPass( text.toUtf8().data() ); std::string s; pass.getShaderRef( s ); @@ -222,6 +240,9 @@ namespace MaterialEditor QString p = passCB->currentText(); CNelMaterialProxy m = nl3dIface->getMaterial(); + if( m.isEmpty() ) + return; + CRenderPassProxy pass = m.getPass( p.toUtf8().data() ); pass.setShaderRef( text.toUtf8().data() ); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.h index c6a8fb000..c69fbfead 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/material_widget.h @@ -53,6 +53,7 @@ namespace MaterialEditor Q_SIGNALS: void propsChanged(); void passChanged( const QString &pass ); + void subMatChanged( int i ); private: void setupConnections(); 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 013bf9db7..62492f61e 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 @@ -214,7 +214,7 @@ namespace MaterialEditor CRenderPassProxy CNelMaterialProxy::getPass( unsigned long i ) { - if( material->count() >= i ) + if( i >= material->count() ) return CRenderPassProxy( NULL ); else return CRenderPassProxy( material->getPass( i ) ); @@ -228,11 +228,11 @@ namespace MaterialEditor CNel3DInterface::CNel3DInterface() { - mat = new NL3D::CDynMaterial(); shaderManager = new NL3D::CShaderManager(); driver = NULL; scene = NULL; mouseListener = NULL; + subMatId = 0; } CNel3DInterface::~CNel3DInterface() @@ -244,6 +244,9 @@ namespace MaterialEditor bool CNel3DInterface::loadMaterial( const char *fname ) { + if( currentShape.empty() ) + return false; + NLMISC::CIFile file; if( !file.open( fname, true ) ) return false; @@ -253,6 +256,7 @@ namespace MaterialEditor return false; newMaterial(); + NL3D::CDynMaterial *mat = currentShape.getMaterial( subMatId ).getObjectPtr()->getDynMat(); mat->clear(); mat->serial( xml ); file.close(); @@ -262,6 +266,9 @@ namespace MaterialEditor bool CNel3DInterface::saveMaterial( const char *fname ) { + if( currentShape.empty() ) + return false; + NLMISC::COFile file; if( !file.open( fname, false, true ) ) return false; @@ -270,7 +277,8 @@ namespace MaterialEditor if( !xml.init( &file ) ) return false; - mat->serial( xml ); + currentShape.getMaterial( subMatId ).getObjectPtr()->getDynMat()->serial( xml ); + xml.flush(); file.close(); @@ -279,13 +287,30 @@ namespace MaterialEditor void CNel3DInterface::newMaterial() { - delete mat; - mat = new NL3D::CDynMaterial(); - + if( currentShape.empty() ) + return; + currentShape.getMaterial( 0 ).getObjectPtr()->getDynMat()->clear(); + } + + bool CNel3DInterface::selectSubMaterial( int id ) + { + if( currentShape.empty() ) + return false; + + if( currentShape.getNumMaterials() < id ) + return false; + + subMatId = id; + + return true; } CNelMaterialProxy CNel3DInterface::getMaterial() { + NL3D::CDynMaterial *mat = NULL; + if( !currentShape.empty() ) + mat = currentShape.getMaterial( subMatId ).getObjectPtr()->getDynMat(); + return CNelMaterialProxy( mat ); } @@ -429,6 +454,12 @@ namespace MaterialEditor clearScene(); currentShape = instance; + int c = currentShape.getNumMaterials(); + for( int i = 0; i < c; i++ ) + currentShape.getMaterial( i ).getObjectPtr()->createDynMat(); + + subMatId = 0; + setupCamera(); return true; @@ -442,6 +473,7 @@ namespace MaterialEditor return; scene->deleteInstance( currentShape ); currentShape = NL3D::UInstance(); + subMatId = 0; } if( driver == NULL ) 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 6bec77b61..0c45cf0fd 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 @@ -107,6 +107,13 @@ namespace MaterialEditor CRenderPassProxy getPass( unsigned long i ); CRenderPassProxy getPass( const char *name ); + bool isEmpty() const{ + if( material == NULL ) + return true; + else + return false; + } + private: NL3D::CDynMaterial *material; }; @@ -131,6 +138,7 @@ namespace MaterialEditor bool saveMaterial( const char *fname ); void newMaterial(); + bool selectSubMaterial( int id ); CNelMaterialProxy getMaterial(); @@ -164,7 +172,8 @@ namespace MaterialEditor private: void setupCamera(); - NL3D::CDynMaterial *mat; + unsigned long subMatId; + NL3D::CShaderManager *shaderManager; NL3D::UDriver *driver; NL3D::UScene *scene; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.cpp index 69aa154a2..0fa2c13dd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.cpp @@ -20,6 +20,8 @@ #include "3rdparty/qtpropertybrowser/qtvariantproperty.h" #include "nel3d_interface.h" +#include + #include namespace MaterialEditor @@ -112,8 +114,28 @@ namespace MaterialEditor switch( p.type ) { case SMatProp::Color: - v = QColor( p.value.c_str() ); - break; + { + std::stringstream ss = p.value; + float c[ 4 ]; + std::fill( c, c + 4, 0.0f ); + + for( int i = 0; i < 4; i++ ) + { + ss >> c[ i ]; + if( !ss.good() ) + break; + } + + QColor color; + color.setRedF( c[ 0 ] ); + color.setGreenF( c[ 1 ] ); + color.setBlueF( c[ 2 ] ); + color.setAlphaF( c[ 3 ] ); + + v = color; + + break; + } case SMatProp::Double: double d; @@ -254,6 +276,9 @@ namespace MaterialEditor return; CNelMaterialProxy m = nel3dIface->getMaterial(); + if( m.isEmpty() ) + return; + CRenderPassProxy p = m.getPass( pass.toUtf8().data() ); std::vector< SMatProp > v; @@ -283,6 +308,47 @@ namespace MaterialEditor } } + void CPropBrowserCtrl::loadPropsForPass( int i ) + { + clearProps(); + + CNelMaterialProxy m = nel3dIface->getMaterial(); + if( m.isEmpty() ) + return; + + CRenderPassProxy p = m.getPass( i ); + + std::string n; + p.getName( n ); + currentPass = n.c_str(); + + std::vector< SMatProp > v; + p.getProperties( v ); + + QtVariantProperty *vp = NULL; + int type = 0; + QVariant qv; + + std::vector< SMatProp >::const_iterator itr = v.begin(); + while( itr != v.end() ) + { + const SMatProp &prop = *itr; + + type = propToQVariant( prop.type ); + + vp = manager->addProperty( type, prop.label.c_str() ); + + if( vp != NULL ) + { + propValToQVariant( prop, qv ); + vp->setValue( qv ); + browser->addProperty( vp ); + propToId[ vp ] = prop.id; + } + ++itr; + } + } + void CPropBrowserCtrl::onValueChanged( QtProperty *p, const QVariant &v ) { QString label = p->propertyName(); @@ -298,6 +364,9 @@ namespace MaterialEditor } CNelMaterialProxy m = nel3dIface->getMaterial(); + if( m.isEmpty() ) + return; + CRenderPassProxy pass = m.getPass( currentPass.toUtf8().data() ); std::map< QtProperty*, std::string >::const_iterator itr diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.h index d602a086c..6d2540123 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/prop_browser_ctrl.h @@ -43,6 +43,7 @@ namespace MaterialEditor void onPropsChanged(); void clearProps(); void loadPropsForPass( const QString &pass ); + void loadPropsForPass( int i ); private Q_SLOTS: void onValueChanged( QtProperty *p, const QVariant &v ); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/render_passes.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/render_passes.cpp index 51dc25a51..0c19e1b29 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/render_passes.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/material_editor/render_passes.cpp @@ -63,6 +63,9 @@ namespace MaterialEditor { clear(); CNelMaterialProxy m = nl3dIface->getMaterial(); + if( m.isEmpty() ) + return; + std::vector< std::string > pl; m.getPassList( pl ); @@ -146,6 +149,9 @@ namespace MaterialEditor delete item; CNelMaterialProxy material = nl3dIface->getMaterial(); + if( material.isEmpty() ) + return; + material.removePass( pass.toUtf8().data() ); if( observer != NULL ) @@ -187,6 +193,9 @@ namespace MaterialEditor item->setText( to ); CNelMaterialProxy material = nl3dIface->getMaterial(); + if( material.isEmpty() ) + return; + material.renamePass( from.toUtf8().data(), to.toUtf8().data() ); if( observer != NULL ) @@ -210,6 +219,9 @@ namespace MaterialEditor QString s = item->text(); CNelMaterialProxy material = nl3dIface->getMaterial(); + if( material.isEmpty() ) + return; + material.movePassUp( s.toUtf8().data() ); if( observer != NULL ) @@ -233,6 +245,9 @@ namespace MaterialEditor QString s = item->text(); CNelMaterialProxy material = nl3dIface->getMaterial(); + if( material.isEmpty() ) + return; + material.movePassDown( s.toUtf8().data() ); if( observer != NULL )