mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-19 19:09:20 +02:00
build 170810. multi-texture materials, reflection map support
This commit is contained in:
143
material.cpp
Normal file
143
material.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "material.h"
|
||||
#include "renderer.h"
|
||||
#include "usefull.h"
|
||||
#include "globals.h"
|
||||
|
||||
bool
|
||||
opengl_material::deserialize( cParser &Input, bool const Loadnow ) {
|
||||
|
||||
bool result { false };
|
||||
while( true == deserialize_mapping( Input, Loadnow ) ) {
|
||||
result = true; // once would suffice but, eh
|
||||
}
|
||||
|
||||
has_alpha = (
|
||||
texture1 != NULL ?
|
||||
GfxRenderer.Texture( texture1 ).has_alpha :
|
||||
false );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// imports member data pair from the config file
|
||||
bool
|
||||
opengl_material::deserialize_mapping( cParser &Input, bool const Loadnow ) {
|
||||
|
||||
if( false == Input.getTokens( 2, true, "\n\r\t;, " ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if( name.rfind( '\\' ) != std::string::npos ) {
|
||||
path = name.substr( 0, name.rfind( '\\' ) + 1 );
|
||||
}
|
||||
|
||||
std::string key, value;
|
||||
Input
|
||||
>> key
|
||||
>> value;
|
||||
|
||||
if( key == "texture1:" ) { texture1 = GfxRenderer.Fetch_Texture( path + value, Loadnow ); }
|
||||
else if( key == "texture2:" ) { texture2 = GfxRenderer.Fetch_Texture( path + value, Loadnow ); }
|
||||
|
||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||
}
|
||||
|
||||
|
||||
// create material object from data stored in specified file.
|
||||
// NOTE: the deferred load parameter is passed to textures defined by material, the material itself is always loaded immediately
|
||||
material_handle
|
||||
material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
||||
|
||||
auto filename { Filename };
|
||||
|
||||
if( filename.find( '|' ) != std::string::npos )
|
||||
filename.erase( filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
||||
|
||||
if( filename.rfind( '.' ) != std::string::npos ) {
|
||||
// we can get extension for .mat or, in legacy files, some image format. just trim it and set it to material file extension
|
||||
filename.erase( filename.rfind( '.' ) );
|
||||
}
|
||||
filename += ".mat";
|
||||
|
||||
for( char &c : filename ) {
|
||||
// change forward slashes to windows ones. NOTE: probably not strictly necessary, but eh
|
||||
c = ( c == '/' ? '\\' : c );
|
||||
}
|
||||
if( filename.find( '\\' ) == std::string::npos ) {
|
||||
// jeśli bieżaca ścieżka do tekstur nie została dodana to dodajemy domyślną
|
||||
filename = szTexturePath + filename;
|
||||
}
|
||||
|
||||
// try to locate requested material in the databank
|
||||
auto const databanklookup = find_in_databank( filename );
|
||||
if( databanklookup != npos ) {
|
||||
return databanklookup;
|
||||
}
|
||||
// if this fails, try to look for it on disk
|
||||
opengl_material material;
|
||||
material.name = filename;
|
||||
auto const disklookup = find_on_disk( filename );
|
||||
if( disklookup != "" ) {
|
||||
cParser materialparser( disklookup, cParser::buffer_FILE );
|
||||
if( false == material.deserialize( materialparser, Loadnow ) ) {
|
||||
// deserialization failed but the .mat file does exist, so we give up at this point
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if there's no .mat file, this could be legacy method of referring just to diffuse texture directly, make a material out of it in such case
|
||||
material.texture1 = GfxRenderer.Fetch_Texture( Filename, Loadnow );
|
||||
if( material.texture1 == NULL ) {
|
||||
// if there's also no texture, give up
|
||||
return NULL;
|
||||
}
|
||||
material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha;
|
||||
}
|
||||
|
||||
material_handle handle = m_materials.size();
|
||||
m_materials.emplace_back( material );
|
||||
m_materialmappings.emplace( material.name, handle );
|
||||
return handle;
|
||||
};
|
||||
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
material_handle
|
||||
material_manager::find_in_databank( std::string const &Materialname ) const {
|
||||
|
||||
auto lookup = m_materialmappings.find( Materialname );
|
||||
if( lookup != m_materialmappings.end() ) {
|
||||
return lookup->second;
|
||||
}
|
||||
// jeszcze próba z dodatkową ścieżką
|
||||
lookup = m_materialmappings.find( szTexturePath + Materialname );
|
||||
|
||||
return (
|
||||
lookup != m_materialmappings.end() ?
|
||||
lookup->second :
|
||||
npos );
|
||||
}
|
||||
|
||||
// checks whether specified file exists.
|
||||
// NOTE: this is direct copy of the method used by texture manager. TBD, TODO: refactor into common routine?
|
||||
std::string
|
||||
material_manager::find_on_disk( std::string const &Materialname ) const {
|
||||
|
||||
return(
|
||||
FileExists( Materialname ) ? Materialname :
|
||||
FileExists( szTexturePath + Materialname ) ? szTexturePath + Materialname :
|
||||
"" );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user